其实“指针”也没那么困难
2013-02-16 14:25
190 查看
指针确实是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相等了。
而a的地址——&a是一个常量,只要程序开始运行,&a的值就不会改变。
可以给p赋值,但是不能给&a赋值
int a=3; int b=5; int *p1=&a; 让p1指向变量a int *p2=&b; 让p2指向变量b p1=p2; 指针p2的值赋值给p1,允许的操作 ,操作后,p1也指向变量b了 &a=&b; 错误的操作,变量的地址之间不能互相赋值
5、指针可以进行加减运算吗?
只有指向相同数据类型的指针,才能进行算术运算。
但是,两个指针不能做加法运算。因为两个地址相加,无任何意义
这好比是:张三住在201寝室,李四住在202寝室,则张三的指针值就是201,李四的指针值是202,两个指针相加得到403,这没有任何意义。 |
#include <stdio.h> int main(void) { int arr[3]={1,2,3}; int *p1=&arr[1]; int *p2=&arr[2]; printf("%d\n",p2-p1); return 0; } 程序运行结果:1,表示p1和p2之间的差值是一个int类型的字节长度指针可以和整数进行加减,指针加1,表示:指针原来的值,加上它指向的变量的数据类型的字节长度,即sizeof(数据类型)
[code]#include <stdio.h> int main(void) { int a=0; int *p=&a; printf("sizeof(int)=%d\n",sizeof(int)); printf("p=%p\n",p); printf("p+1=%p\n",p+1); return 0; } 程序运行结果: sizeof(int)=4 p=0012FF60 p+1=0012FF64
这表示,p+1等于0012FF60+sizeof(int)==0012FF60+4==0012FF64
指针减一就和指针加1的含义相反了。
指针加n:指针原来的值+n×sizeof(指针指向的变量数据类型)
指针减n;指针原来的值-n×sizeof(指针指向的变量数据类型)
对于指针和整数加减,只适用于数组中,当指针p指向数组中某一个元素时,指针p+1,就等于让指针p指向数组下一个元素,指针p-1,就等于让指针p指向数组上一个元素。
6、总结:指针的用法流程
(1)先声明其他变量
(2)再声明相应类型的指针,让指针赋值让&变量的值
(3)如果操作的时候,给指针带*号,表示从指针取值,如果不带“*”号,表示指针与指针之间进行地址操作。
本文就针对指针的概念进行的部分阐述,相信大家只要仔细理解,一定能够攻克指针这一难关的。
[/code]本文出自 “捷哥的IT小屋” 博客,请务必保留此出处http://wzjxzht.blog.51cto.com/4866070/1134105
相关文章推荐
- 认识指针(c语言),其实指针没有你想的那么难!
- ArrayList其实就那么一回事儿之源码浅析
- 指针,其实很危险
- HashMap其实就那么一回事儿之源码浅析
- intptr_t 其实不是指针类型 .
- 手机其实没有你想象得那么安全!
- 写作其实没有你想象的那么难
- MacBook Pro安装Photoshop且支持Retina有你们说的那么困难吗!
- 人生感悟:你其实远没有自己想象中那么努力
- delphi中的对象其实也是一种指针
- webpack其实没那么可怕——官方文档解读
- 证明连续函数的一致连续性为何那么困难?
- CCRANDOM_0_1()其实不那么好用 爱上C++随机数的缘由
- 其实,我感觉致青春没我想象的那么好看,虽然我比较喜欢赵薇
- 写作其实没有你想象的那么难
- Dubbo项目配置,其实没那么神乎
- 【转】ArrayList其实就那么一回事儿之源码浅析
- string类型其实就是一个指针
- 6大细节证明 你其实没那么聪明
- 中国盗版率其实并没有那么高