王学岗c语言指针和指针运算
来源:互联网 发布:指南针炒股软件收费版 编辑:程序博客网 时间:2024/05/16 04:50
关于指针有一片文章写的详尽又容易了解:http://blog.chinaunix.net/uid-22889411-id-59688.html
(1)指针和地址的区别
//指针有类型 地址没有类型,需要强制类型转化才能赋值给指针变量
int* p=(int*)0x44fc28
(2)指针使用之前必须要有初始值
void main(){ int* p; //报空指针异常 printf("%#x",p); getchar();}
上文报错处可以这样写
int* p=NULL;
(3)指针变量多次赋值为不同变量的地址
void main(){ int* p=NULL; printf("%#x",p); //把200当做一个内存地址赋值给了指针变量(16进制) p = 200; //打印指针变量对应的值 printf("%d\n", *p); getchar();}
打印输出发现报错
200转成16进制,由于数字比较小,系统本身已经占用了这块内存区域,内存地址已经被分配掉了,然而系统本身内存数据不允许访问!一般情况下,我们不要直接给指针变量赋值为整数。
(4)NDK指针地址,二级指针
int a=100; int b=200; int* p1=&a; //p1保存的是a变量的地址——0x0022FDE0,通过该地址可以查询到a的值是100 printf("p1地址:%#x\n",&p1); //指针变量也是变量,同样占据了内存空间,同样有地址,因此可以用一个指针指向它 //这就称之为二级指针, //定义一个二级指针p2,&p1指针的地址 int** p2=&p1; **p2=1000; printf("二级指针的地址:%#x",&p2); //a的值会变成1000,*是取值,&是取地址 //p2保存的数据是p1的地址,*p2上的数据是p1上面的数据 //p1保存的数据是a的地址,所以**p2实际上就是a的值 printf("\na的值:%d",a); system("pause");
(4)指针运算(赋值运算符和算术运算)
算术运算(+,-,*,/)
void main(){ int ids[]= {22,33,34,44,34,46,22,90}; //打印数组 printf("数组%#x\n",ids); //数组第一个元素地址 printf("数组第一个元素地址 %#x",&ids[0]); //两个值相同 system("pause");}
控制台输出两个值相同
ids是常量指针,存储的是数组的首地址
继续大家会发现,数组在内存中的存储是连续的
我们 看下指针如何运算:
void main(){ int ids[] = { 22, 33, 34, 44, 34, 46, 22, 90 }; //打印数组 printf("数组%#x\n", ids); //数组第一个元素地址 printf("数组第一个元素地址 %#x\n", &ids[0]); //两个值相同 int* p = ids; p++; printf("地址:%#x值:%d",p,*p); system("pause");}
注意,p++后,*p的值变成了33(既数组的第二个元素),地址也变成了第二个元素的地址,因为int类型占4个字节,+1后就相当于+了一个int字节数,就是字节由de8+4=dec;
总结:p++每次向前移动sizeof(数据类型)个字节
下面我使用指针遍历数组
void main(){ int ids[] = { 22, 33, 34, 44, 34, 46, 22, 90 }; //打印数组 printf("数组%#x\n", ids); //数组第一个元素地址 printf("数组第一个元素地址 %#x\n", &ids[0]); //两个值相同 int* p = ids; p++; printf("地址:%#x值:%d\n",p,*p); for (; p < ids + 8;p++){ printf("值:%d\n",*p); } system("pause");}
注意:让指针递增或者递减,一般情况下只有在数组遍历的时候才有意义,是基于数组在内存中的象形排列方式;
(5)指针运算(通过使用指针循环给数组赋值)
传统方法赋值
void main(){ int ids[6] ; int*p = ids; //传统的写法赋值 int i = 0; for (; i < 6; i++){ ids[i] = i * 2; } //输出 i = 0; for (; i < 6; i++){ printf("值:%d",ids[i]); } system("pause");}
指针赋值:
void main(){ int ids[6] ; int*p = ids; int i = 0; for (; p < ids + 6;p++){ *p = i * 2; i++; } i = 0; for (; i < 6; i++){ printf("值:%d",ids[i]); } system("pause");}
运行结果和上次运行结果一样;
(6)指针运算,数组内部的加减
void main(){ int ids[] = {34,5,65,43,66,77,99}; int* p = ids; p = p + 3; //*p的值是43 printf("值:%d\n地址:%#x\n",*p,p); system("pause");}
(7)指针运算指针大小比较
大小比较,都是在遍历数组的时候运用,其他情况下没用,指针地址相等,并不代表值相等;因为指针有类型
(8)NDK-指针运算-指针与数组的几种写法
int _tmain(int argc, _TCHAR* argv[]){ int ids[]={52,84,86,92,48,47,15,32}; int i=0; for(;i<7;i++){ //输出数据 printf("%d %#x\n",ids[i],&ids[i]); //ids就是常亮指针,就是一个首地址 //ids+0等价于 &ids[0] //ids+1等价于 &ids[1] //以此类推…… //ids+i 等价于&ids[i] //在地址墙面加*就是取值,所以 //*(ids+i) 等价于 ids[i] printf("%d %#x\n",*(ids+i),ids+i); } return 0;}
(9)指针引用二维数组
int _tmain(int argc, _TCHAR* argv[]){ //两行三列的二维数组 int ids[2][3]={23,58,4,58,69,79}; //遍历二维数组,外层循环控制行,内存循环控制列 int i=0; for(;i<2;i++){ int j=0; for(;j<3;j++){ printf("值:%d,地址:%#x ",ids[i][j],& ids[i][j]); } //换行 printf("\n"); } printf("ids:%#x &ids:%#x *ids:%#x ",ids,&ids,*ids); getchar(); return 0;}
大家看下,我们发现ids,&ids,*ids的三个地址是一模一样。注意,地址相同,但并不代表值相同
int _tmain(int argc, _TCHAR* argv[]){ //两行三列的二维数组 int ids[2][3]={23,58,4,58,69,79}; //遍历二维数组,外层循环控制行,内存循环控制列 int i=0; for(;i<2;i++){ int j=0; for(;j<3;j++){ printf("值:%d,地址:%#x ",ids[i][j],& ids[i][j]); } //换行 printf("\n"); } printf("ids:%#x &ids:%#x *ids:%#x\n ",ids,&ids,*ids); printf("长度%d, 长度%d, 长度%d",sizeof(*ids),sizeof(*&ids),sizeof(**ids)); getchar(); return 0;}
大家看下打印结果:
大家注意了,长度12说明ids代表行指针(指向一个拥有三个数组的元素),每行3个int类型,每个int类型是4个字节;
长度24说明&ids代表的是一个二维数组指针,24个int类型,每个int类型4个字节;
长度4,说明*ids代表数组的类型,指向该数组的数据类型的指针;如果是double类型的数组,则此处将是8;
再看下下面的代码
int _tmain(int argc, _TCHAR* argv[]){ //两行三列的二维数组 int ids[2][3]={23,58,4,58,69,79}; //打印结果是第一行的第一个元素23,即ids[0][0] printf("值:%d",**ids); getchar(); return 0;}
我们继续来推导,看下面的代码
int _tmain(int argc, _TCHAR* argv[]){ //两行三列的二维数组 int ids[2][3]={23,58,4,58,69,79}; //打印第二行,第二列 printf("值:%d\n",ids[1][1]); //用指针来打印第二行,第二列 printf("值%d",*(*(ids+1)+1)); getchar(); return 0;}
ids代表行指针:ids+0代表第一行,
ids+1代表第二行,
以此类推,第N行为ids+n;
取某一行的第一个元素的指针:*(ids+i)
第一行第一个元素指针:*(ids+0)
第二行第一个元素指针:*(ids+1)
以此类推:*(ids+i)
ids代表首地址所以
取第一行第一个指针:*ids+0;
取第一行第二个指针:*ids+1;
取第一行第三个指针:*ids+2;
以此类推:*ids+j
把以上两个推理结合下,取第二行第二个元素的指针:
*(ids+1)+1
我们可以得出结论:(ids+i)+j,获取该地址的值为(*(ids+i)+j)
- 王学岗c语言指针和指针运算
- C语言指针的运算
- C语言指针的运算
- C语言:指针及其运算
- C语言:指针的运算
- c语言指针初探 一指针运算与多级指针
- C语言中指针初始化和常规运算
- C语言指针数组和数组指针
- C语言指针数组和数组指针
- C语言:行指针和列指针
- C语言指针数组和数组指针
- C语言指针数组和数组指针
- C语言--指针函数和函数指针
- C语言指针数组和数组指针
- C语言指针数组和数组指针
- C语言指针数组和数组指针
- C语言指针数组和数组指针
- C语言 数组指针和指针数组
- 2.24
- leetcode题解-299. Bulls and Cows
- 素数环
- React 父子组建生命周期
- Android:打开系统联系人界面并获取数据
- 王学岗c语言指针和指针运算
- 大文本的分割
- Prime Path
- epoll回声服务器
- 【毕业设计】图灵机器人的实现
- 六,(补充)ES6给Math对象新增的17个函数
- Android加载网络图片Glide学习
- 过滤/ObReferenceObjectByName/XT
- modinfo命令找不到modules.dep文件的解决办法