该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
指针确实是C/C++学习过程中的一大难点,但是它真正的难度就在于你很容易把它和普通变量搞混淆,更搞不清楚什么时候该用指针。本文针对初学者,将指针的概念逐步展示出来,希望能给初学者一点点帮助。
1、指针是什么东西?
指针其实是一个变量,它保存的值是其他变量在内存中的地址。
所以,在声明指针的时候,必须是要先有其他变量,才能有指针。而且,只能将既有变量用“&”取地址以后赋值给指针。下面的代码列举出了两种指针的声明方式,必须是先有变量num1,才能有指针p。
int
num1=3;
int *p=NULL; //如果声明的时候不立即给指针赋值,则指针必须为空值
p=&num1;
int num1=3;
int *p=&num1; //声明的同时给指针赋值
2、为什么指针也要带数据类型名?
我们来看代码中的int
*p,千万不要认为这个指针p是int类型的。指针自己就是一个独立的数据类型,在指针前面带上数据类型名,表示:这个指针保存的是某种数据类型的地址,即“指向某种类型”。如果是int
*p,就表示:这个指针保存的是一个int变量的地址,即:指向一个int类型的变量。
什么叫“指向”?如果一个指针p保存了变量num1的地址,即将&num1赋值给p,就说指针p指向num1.
指针前面带的数据类型,一定要和它指向的变量数据类型吻合
int
num1=3;
int *p=&num1; 正确
char
*p=&num1; 错误,指针指向的类型和num1的类型不匹配
3、不同地方的“*”有着不同的含义
在声明指针的时候,必须有“*”号,表示:我声明的变量是一个指针。声明指针的时候,“*”号表示的是指针变量的特殊标记。
int
*p; 声明一个指向int类型变量的指针p
int p; (没有“*”)声明的是一个普通int型变量p
float
*pt; 声明的是一个指向float类型变量的指针pt
float pt; 声明的是一个普通的float型变量pt
在使用指针的时候,“*”号的含义就表示:从指针标记的地址中取出里面的值。只有在对指针做取值操作的时候,才允许给指针带上“*”,如果是给指针赋值为其他变量的地址,则指针不能带“*”号了。
int
*a=9;
int *p=NULL;
p=&a; //给指针赋值地址时不能带“*”号
*p=8; //给指针赋值其他整数值时,必须带“*”号
*p=2.5
错误操作,因为p是一个指向int类型的指针,*p只能赋值整数
p=6; 错误操作,指针本身不能赋值为任何整数
p++ 可以操作,但一般不这么使用,让指针指向下一个int类型的变量(这个变量必须存在)
(*p)++
正确操作,让指针指向的变量值进行自加
有人会问了:既然内存地址是表示成一个16进制的整数,那也可以用一个long long
int来表示地址,干嘛要用指针呢? 原因很简单:用一个long long
int的变量确实可以标记其他变量的地址,但是非指针类型的变量只能标记地址,不支持取值操作
int num1=9;
int
*p1=&num1; //用指针标记num1的地址
long long int p2=&num1;
//用超长整形变量p2标记num1的地址
printf("变量num1的地址是:%p\n",p1);
printf("变量num1的地址是:%p\n",p2);
//这里,他们输出的结果都是一样的
区别在这里:
*p1; 正确,可以用“*”从指针p中取出它指向的变量(num1)的值
*p2; 错误,(会提示“没有左值”)
4、指针和变量的地址到底有什么关系?
假设有一个指针:int
*p=&a,此时用*p、a、*(&a)都可以取出a的值。那么问:p和&a有什么联系和区别?
p是一个指针,而指针是一个变量,它的值可以任意改变,只有当p=&a操作时,p的值才和&a的值相同,如果p被赋值了其他的值,它就不和&a相等了。