p,&p,*p的区别

深入理解C++指针与数组的区别及使用注意事项

一、区别

 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的别名

太好了,我们来一步一步地讲清楚: > **`*p`、`&p` 和 `int *p`** 看起来很像,但它们的含义和用途是不一样的。我们用大白话和例子来解释。 --- ## 一、`int *p;` 是什么? 这是**定义一个指针变量 p**,它将来可以保存一个地址。 ```c int *p; ``` 这句代码的意思是: > “我要定义一个叫 `p` 的变量,它是用来存一个 `int` 类型变量地址的指针。” 你可以把它理解成: > “我准备了一个小盒子(`p`),这个盒子里将来要放一个整数的‘门牌号’。” --- ## 二、`&p` 是什么? 这是**取变量 p 的地址**。 我们先来看一个例子: ```c int a = 10; int *p = &a; ``` - `&a` 表示取变量 `a` 的地址,也就是它的“家的门牌号”。 - 把这个地址存到 `p` 里,就是“`p` 指向 `a`”。 那如果写: ```c printf("%p", &p); ``` - 就是在输出 `p` 自己的地址! 就像:小盒子(`p`)也有它自己的位置(在内存里),`&p` 就是它的位置。 --- ## 三、`*p` 是什么? 这是**“去 p 所指向的地方取值”**,也叫“解引用”。 继续看例子: ```c int a = 10; int *p = &a; printf("%d", *p); // 输出 10 ``` - `*p` 就是:拿着 `p` 里的地址去找它指向的变量,然后把那个变量的值取出来。 - 你可以理解成:用 `p` 找到 `a`,然后打开门,看看里面装的是什么。 --- ## 四、三者对比总结(大白话) | 写法 | 含义 | 举个例子 | 通俗解释 | |----------|------|----------|-----------| | `int *p;` | 定义一个指针变量 | `int *p;` | 我准备了一个盒子,将来装一个变量的地址 | | `&p` | 取指针变量自己的地址 | `printf("%p", &p);` | 指针 `p` 自己的“家在哪儿?” | | `*p` | 取指针指向的内容 | `printf("%d", *p);` | 去 `p` 指向的地方拿数据出来 | --- ## 🧠 总结一句话: > **`int *p` 是定义指针;`&p` 是问指针自己住在哪;`*p` 是问指针指着的东西是什么。** --- ## ✅ 知识点 1. **指针的定义** `int *p;` 是定义一个指向 `int` 类型的指针变量。 2. **取地址运算符 `&`** `&变量` 可以获取变量的内存地址。 3. **解引用运算符 `*`** `*指针` 表示访问指针所指向的内存中的值。 --- 如果你还想了解多级指针(比如 `int **p`)或者数组和指针的更多联系,我也可以继续讲 😄
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值