p,&p,*p的区别

一、区别

 int z=0;
 int &x = z;//引用,x与z指向同一内存单元
 int *y;
 y = &x;//0x0012ff14 p本身所占内存单元的地址

 cout <<x<<" "<<*y<<" "<<z<<endl;

 

下面是摘抄别人的一段测试程序。
void   test(){
      int   a=8;
      int   *p=&a;
      p=(int   *)malloc(N*sizeof(int));
    //   printf( "%d/n ",*p);
    //a.   cout < <&p;                  //0x0012ff14 p本身所占内存单元的地址
    //b.   cout < <*p;                  //8 p所指向的内存单元的值
      c.   cout < <p;                     //0x000431c50 p所指向的内存单元的地址
}

    从测试的结果很容易看出来,*P是一个指针变量,它存储的数据是地址,并且也只能存储地址,所以在给*P赋值时,请您确认等号右边的值是不是一个地址。如果不是,那么您的程序将会出现BUG,(或许您是一位优秀的汇编写手,那么请您处理好该指针变量)。
    另外还要说明的是int   *p=&a;等价于int *p ; p = &a;
   
应该注意的2点是:
1.给指针只能传地址,不能传值.否则要做强制类型转换.
2.在做类型转换和赋值时候,应该注意赋值的类型匹配.

 

指针与数组的区别:

很多初学者弄不清指针和数组到底有什么样的关系。我现在就告诉你:他们之间没有
任何关系!只是他们经常穿着相似的衣服来逗你玩罢了。
指针就是指针,指针变量在32 位系统下,永远占4 个byte,其值为某一个内存的地址。
指针可以指向任何地方,但是不是任何地方你都能通过这个指针变量访问到。
数组就是数组,其大小与元素的类型和个数有关。定义数组时必须指定其元素的类型
和个数。数组可以存任何类型的数据,但不能存函数。
既然它们之间没有任何关系,那为何很多人把数组和指针混淆呢?甚至很多人认为指
针和数组是一样的。这就与市面上的C 语言的书有关,几乎没有一本书把这个问题讲透彻,
讲明白了。

#include <stdio.h>
intmain()
{
int a[5]={1,2,3,4,5};
int *ptr1=(int *)(&a+1);         //a数组是一个整体,sizeof(a)=20;&a表示数组的首地址,&a+1会相当于加20个字节长度。
int *ptr2=(int *)((int)a+1);     //a强制转换为int型后,相当于整数加一,所以这只是相当于地址加了一个字节。再转换为地址存入ptr2
int *ptr3=(int *)(a+1);   //这个是大家非常熟悉的了,数组a作为左值时相当于&a[0],它加一相当于加了一个数组类型的长度,即4字节(整形)。a不能作为右值。
printf("%x,%x,%x",ptr1[-1],*ptr2,ptr3);
printf("%x,%x,%x",ptr1,ptr2,ptr3);
return 0;
}


#include<iostream>
usingnamespace std;
int g =300;
void print(int p,int q)
{  
cout<< p<< endl<< q<< endl;
}
voidset(int*&p,int* q)
{  
p=&g;// p是引用类型,可以改变传进参数的指向        
q=&g;// q不会
}
int main()
{  
int a =10, b=20;    
int*pa=&a,*pb=&b;    
print(a, b);  
cout<< pa<< endl<< pb<< endl;    
set(pa, pb); // pa现在指向g,但pb还是指向b,这就是引用和非引用的差别   
print(a, b);  
print(*pa,*pb);    
return0;

}

int *&p是指针的引用,不会为p开辟空间,只是一个名字,此时相当直接对pa操作,后者开辟了个临时指针,得到pa的地址,根据指针指向地址修改pa所指向的值!两者效果是一样,但具体的实际过程有区别!


二、*&p表示什么意思

void main()
{
int *a;
int *&p=a;
int b=10;
p=&b;
}
int a=10;
int p=a;
这种情况,p与a是不同的变量,这里是将a的值赋给p
int &p=a; 
即 p是a 的别名,p和a其实是同一个整形变量,两个占用同一块内存空间,如果有 p=15;那么a也是15,修改p与修改a是完全等价的

那么
int *a;
int * &p=a; 
很容易理解,把 int * 看成一个类型,a就是一个整型指针,p 是a的别名

<think>好的,我现在需要仔细分析用户提出的C语言问题。题目是给出四个表达式:*&p、*&x、&*x、&*p,其中哪个是错误的。用户提供的代码片段是`float x, *p = &x;`,所以首先我要明确各个变量和指针的关系。 首先,我需要回忆C语言中指针和运算符的基本概念。指针变量存储的是另一个变量的地址,而取地址运算符&用于获取变量的地址,解引用运算符*用于访问指针所指向的值。 让我们先分解代码:`float x, *p = &x;`。这里声明了一个浮点变量x和一个指向浮点的指针p,并且p被初始化为x的地址。因此,p指向x,即p的值是&x,而*p就是x的值。 接下来逐个分析四个表达式: 1. **\*&p**:首先,&p是获取指针p本身的地址,这个地址的类型是float**(指向float指针的指针)。然后,对这个地址进行解引用操作,即*&p,得到的是p本身,也就是p的值,即x的地址。所以这个表达式是正确的,类型是float*。 2. **\*&x**:这里&x是获取变量x的地址,类型是float*。解引用这个地址,即*&x,等同于x本身,所以这个表达式是正确的,类型是float。 3. **&*x**:这一步需要先解引用x,但x是一个float类型的变量,不是指针。对非指针类型的变量使用解引用运算符*会导致编译错误,因为x不是一个指针,无法解引用。因此,这个表达式是错误的。 4. **&*p**:p是一个指向float的指针,*p解引用得到x的值,即float类型。然后取这个值的地址,即&(*p),这相当于取x的地址,也就是p本身。所以这个表达式是正确的,等同于p,类型是float*。 现在需要确认每个步骤是否正确。特别是第三个表达式&*x,是否真的错误。因为x是一个float变量,不是指针,所以*操作符无法应用在x上,这会引发编译错误。例如,在C语言中,如果尝试写*5,编译器会报错,因为5不是一个指针。同理,x是一个float,所以*x是非法的,导致整个表达式&*x错误。 剩下的三个表达式虽然看起来有些绕,但都是合法的。例如,*&p等同于p,因为先取p的地址再解引用;&*p等同于&x,因为*p是x,取地址就是&x,而p本身已经存储了&x,所以这个表达式等同于p。而*&x等同于x,也是正确的。 因此,错误的表达式是第三个:&*x。</think>让我们逐步分析表达式 `float x, *p = &x;` 后的四个选项: ```c float x, *p = &x; // p 是指向x的指针,存储x的地址 ``` ### 表达式分析: 1. **`*&p`** - `&p`:取指针变量 `p` 的地址,类型是 `float**` - `*&p`:对地址解引用,得到 `p` 本身(即 `p` 的值,也就是 `x` 的地址) - **合法**,等价于 `p`,类型为 `float*` 2. **`*&x`** - `&x`:取变量 `x` 的地址,类型是 `float*` - `*&x`:对地址解引用,得到 `x` 本身 - **合法**,等价于 `x`,类型为 `float` 3. **`&*x`** - `*x`:尝试解引用 `x`,但 `x` 是 `float` 类型,非指针,**非法操作** - 编译器会报错:`invalid type argument of unary '*'` 4. **`&*p`** - `*p`:解引用指针 `p`,得到 `x` 的值,类型是 `float` - `&*p`:取 `x` 的地址,等价于 `p` - **合法**,类型为 `float*` ### 错误原因总结: - **`&*x`** 是唯一错误表达式:`x` 是基本类型变量,不能使用解引用运算符 `*`。 ### 附:表达式类型验证表 | 表达式 | 类型 | 合法性 | |--------|-----------|--------| | `*&p` | `float*` | ✔️ | | `*&x` | `float` | ✔️ | | `&*x` | 无(错误)| ❌ | | `&*p` | `float*` | ✔️ | **结论**:错误的表达式是 **`&*x`**。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值