忙里偷闲( ˇˍˇ )闲里偷学【C语言篇】——(5)有趣的指针
一、指针是C语言的灵魂
# include <stdio.h>int main(){int *p; //p是变量名,int *表示p变量存放的是int类型变量的地址,p是一个指针变量int i = 3;//p = i; 这样写是错误的//p = 4; 这样写是错误的p = &i; //将i变量的地址给p变量 //p保存了i的地址,因此p指向i,修改p的值不影响i的值,修改i的值也不影响p的值return 0; }
# include <stdio.h>int main(){int *p; //不表示定义了一个名字叫做 *p的变量 //应该这样理解:p是变量名,p变量的数据类型是 int *类型 //int *类型实际就是存放int变量地址的类型int i = 3;p = &i;printf("*P = %d\n", *p);printf("i = %d\n", i);return 0; }
注释:1.如果p是个指针变量,并且p存放了普通变量i的地址,则p指向了普通变量
2.*P 完全等同于 普通变量i (有i出现的地方都可以替换成*p)指针和指针变量的区别:
1.指针就是地址,地址就是指针,地址就是内存单元的编号,所以指针就是内存单元的编号
2.指针变量存放地址的变量,也就是说指针变量是存放内存单元编号的变量
3.指针和指针变量是两个不同的概念,但是要注意通常我们叙述时会把指针变量简称为指针,实际它们的含义不一样
二、指针的重要性:
1.表示一些复杂的数据结构
2.快速的传递数据
3.使函数返回一个以上的值(函数只能返回一个值)
4.能直接访问硬件
5.能够方便的处理字符串
6.是理解面向对象语言中引用的基础
# include <stdio.h>int f(int a, int b); void g(int * p ,int * q);int main(void){int a = 100;int b = 200;// a = f(a, b);g(&a, &b);printf("a = %d, b = %d\n", a, b);return 0; } //只能修改一个值 int f(int a, int b){return 1; } //这样被调函数可以修改主调函数一个以上的值 void g(int * p ,int * q){*p = 1;*q = 2; }
三、指针的定义
1、地址:内存单元的编号,地址是从零开始的非负整数。
2、范围:
控制总线
CPU <----> 数据总线 <-----> 内存条
地址总线
控制线控制数据传输的方向
数据线是传输数据
地址线是确定是控制哪个内存单元cup<-----> 数据总线 <-----> 内存条
一根线控制两个 0和1
两根线控制四个
n根线控制2的n次方个单元(字节)(每个单元是8位)32位机 2x10^32
1G=2X10^30B(字节)
2x10^32 ~= 2X10^30*4 所以内存最大4G3、指针:指针就是地址,地址就是指针,指针变量就是存放内存单元编号的变量。
指针本质就是一个操作受限(不能运算,只是编号)的非负整数(地址)
四、指针的分类
1、基本类型的指针
常见错误1:
# include <stdio.h>int main(void){int *p; //p指向一个垃圾值的地址,也就是一个垃圾地址int i = 5;*p = i; // 就是将i的值给了一个不知道的地址,这样写不对printf("%d\n", *p);return 0; }
常见错误2:
# include <stdio.h>int main(void){int i = 5;int *p;int *q;p = &i//*q = p; 语法编译出错//*q = *p; error q指向一个垃圾地址q = p; // error 可以读 q里面的垃圾地址,但是不能读*q的值,没有控制权限。printf("%d\n", *q);return 0; }
一个经典的指针程序:
# include <stdio.h>void huhuan(int i, int j); void zhizhenhuhuan(int * a, int * b); void huhuan3(int * a, int * b);int main(void){int a = 3;int b = 5;// huhuan(a, b); // zhizhenhuhuan(&a, &b);huhuan3(&a, &b);printf("a = %d,b = %d\n", a, b);return 0; }void huhuan(int a, int b){ //不能完成互换,a,b是形参,单独分配内存int t;t = a;a = b;b = t; }void zhizhenhuhuan(int * a, int * b){ //不能完成互换,互换了指针的指向int * t;t = a;a = b;b = t; }void huhuan3(int * a, int * b){ //可以完成互换,传递的是地址,交换的是地址指向的值int t;t = *a;*a = *b;*b = t; }
*的含义:
♥乘法 c = a*b;
♥定义指针变量 int * p;
♥取值运算符 *p
2、指针和数组的关系
一维数组名是个指针常量,它存放的是数组第一个元素地址
int a[5]; int b[5]; //a = b 是错误的 a,b都是常量
# include <stdio.h>int main(void){int a[5];printf("%#x\n", &a[0]);printf("%#x\n", a);return 0; }
输出结果:0x12ff6c
0x12ff6c
如果p是个指针变量,则p[i]永远等价于 *(p+i)
确定一个一维数组需要两个参数:
数组第一个元素的地址
数组的长度
//f函数可以输出任何一个一维数组的内容 # include <stdio.h>void f(int * pArr, int len){int i;for (i=0; i<len; i++)printf("%d ", *(pArr+i));printf("\n"); } int main(void){int a[5] = {1, 2, 3, 4, 5};int b[6] = {-1, -2, -3, 4, 5, -6};int c[100] = {1, 99, 22, 33};f(a, 5); //确定一个数组:数组首地址和长度f(b, 6);f(c, 100);return 0; }
# include <stdio.h>void f(int * pArr, int len){pArr[3] = 88; //pArr[3]等价于a[3]也等价于*(a+3)和*(pArr+3) // *a==a[0] }int main(void){int a[6] = {1, 2, 3, 4, 5, 6};printf("%d\n", a[3]);f(a, 6); // a和pArr都指向数组的第一个元素printf("%d\n", *(a+3));return 0; }
五、指针变量的运算
指针变量不能相加,不能相乘,也不能相除(这些运算没有意义)
如果两个指针变量指向的是同一块连续空间中得不同的存储单元,则这两个指针才可以相减(这样减才有意义)
# include <stdio.h>int main(void){int i = 5;int j = 10;int * p = &i;int * q = &j;//此时p和q不能相减int a[5];p = &a[2];q = &a[4];printf("相减的结果为:%d\n", p-q);//此时p和q可以相减,相减的值指p和q单元相隔的个数return 0; }
结果为:相减的结果为:-2
六、指针变量长度
预备知识:
sizeof(数据类型);或者 sizeof(变量名);返回该数据类型所占的字节数
例如: sizeof(int) = 4 sizeof(char) = 1
# include <stdio.h>int main(void){char ch = 'A';int i = 90;double x = 66.6;char * p = &ch;int *q = &i;double *r = &x;printf("%d %d %d\n", sizeof(p), sizeof(q), sizeof(r)); }
输出的结果:4 4 4
七、多级指针
# include <stdio.h>int main(void){int i = 10;int * p = &i;int ** q = &p;int *** r = &q;printf("i = %d\n", ***r);return 0; }
结果: i = 10
忙里偷闲( ˇˍˇ )闲里偷学【C语言篇】——(5)有趣的指针相关推荐
- 忙里偷闲( ˇˍˇ )闲里偷学【C语言篇】——(9)链表
我们至少可以通过两种结构来存储数据 数组 1.需要一整块连续的存储空间,内存中可能没有 2.插入元素,删除元素效率极低. 3.查找数据快 链表 1.查找效率低 2.不需要一块连续的内存空间 3.插入删 ...
- 忙里偷闲( ˇˍˇ )闲里偷学【C语言篇】——(6)动态内存分配
一.传统数组的缺点: 1.数组的长度必须事先定制,且只能是常整数,不能是变量 int len = 5; int a[len]; //error 2.传统形式定义的数组,该程序的内存程序员无法手动释放 ...
- 忙里偷闲( ˇˍˇ )闲里偷学【C语言篇】——(4)for == while ?
一.for和while等价替换 int i = 1; for (i; i<=100; i++){sum = sum + 1; } int i = 1; while(i<=100){sum ...
- 趣学 C 语言(九)—— 复杂指针解析
函数指针是指针变量,而不是函数,可见在 C 语言的世界里,函数不可以为变量,尽管如此,函数指针的存在使 C 语言离函数式编程一步之遥. 函数指针 函数指针是指针(一种特殊的指针),而指针是一种变量,函 ...
- 自学c语言后的感受,C语言感触篇:十年之后重学C语言,岁月蹉跎,我听闻你始终一个人...
C语言感触篇:十年之后重学C语言,岁月蹉跎,我听闻你始终一个人 我只是C粉 1.1 多次自学,不得其法 距离大学时学习C语言已有十个年头了.印象里最深的就是当时一位海归老师,在讲课时流露出对K& ...
- 从0开始学c语言-终篇41-练习、学习分享
CSDN话题挑战赛第2期 参赛话题:学习笔记 终于,来到了终篇,我坚持做到了!每天一篇博客记录自己的学习(虽然中间有两天去干农活而断更了)!啊呜呜呜呜~激动! 但是,这不会是我的终点,这是新的起点.之 ...
- 后端开发需要学什么_都2020年了,还在纠结学什么语言?| 后端篇
几个礼拜前,一个学弟问我: "Ray,我打算之后要找工作了,不过现在自己没有特别深入的语言,最近想找一门好好学一下,你觉得学什么语言好呀?" 我表示:"这个要看你求职方向 ...
- 大学所有专业都要学c语言吗,是不是大学里的所有专业都会学一些计算机基础内容...
是不是大学里的所有专业都会学一些计算机基础内容以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 是不是大学里的所有专业都会 ...
- 我从别人那里偷学的前端调试小技巧(浏览器篇)
发现光,欣赏光,学习光 每个人身上都有着不同的闪光点,把焦点凝结在缺点上只会让互相难过.转移焦点,放在他的优点上,你会发现,唔还不错.而且,你还可以学习它,让你变得更棒.(我越来越擅长写鸡汤了???? ...
最新文章
- 百度离职员工吐槽:整天除了工作还要演好戏,拍马屁,心太累!
- R语言bioconductor包—maftools的使用
- 十年沉淀、厚积薄发,百度CTO王海峰秀出NLP十年成果
- 碰撞,处理碰撞,发射 Learn Unreal Engine (with C++)
- [资源]基于 Pytorch 的 TorchGAN开源了!
- Coursera NLP 笔记02
- js中(function(){…})()立即执行函数写法理解
- CTO 说了,如果发现谁用 SELECT * 查询直接开除
- EXCLE调用REFPROP操作以及问题
- Eclipse启动时弹出Subversive Connector Discovery窗口解决办法
- matlab 画图 浓淡有别,matlab画图命令汇总
- python:类基础
- 想转行学IT,Java怎么样?
- mysql 完美卸载
- SpringCloudRPC远程调用核心原理:Feign弹性RPC客户端的重要组件
- matlab学霸表白公式,一个理科学霸的表白:数学公式的超酷表白
- 洛谷刷题——P1192 台阶问题
- 中专计算机毕业生登记表自我鉴定,中专毕业生登记表自我鉴定范文(精选5篇)...
- 工作流网(workflow net)
- 独立显卡怎么安装-安装独立显卡简易视频安装教程