我也要学C语言-第十四章:指针与数组
伙伴们!我们一起再继续加油学习关于C指针的后续部分,今天我们要学习的是指针与数组。昨天我们一起学习了linux的安装以及emacs编辑器的打开输入保存与退出,以及gdb的最基础的几个调试功能,大家都熟练掌握了吗?有些朋友说难,我想是因为你没有认真轻言放弃啊,加油啊!今天我练习了半天emacs的快速指南,大家也记得经常去练习哦!一起努力写出程序来哦!(还有我想声明一下:本博客只是为了加强自己的专注力,和对比我晚学2天C语言的朋友们提供一些学习上的参考,对有些所谓的“大牛”对我的讽刺,比如说我什么哗众取宠!之类的言语,你趁早关掉你的浏览器!你只是1个比我先学习几年或者几十年的1个人。真正的大牛是像牛一样辛勤的工作,吃的草,出的是奶。)(从今天到永远我写的代码都将不符合C标准,大家请注意改正过来!)
指针与数组
数组既然也占有存储单元,所以它也有自己的内存地址,有了内存地址呢,我们的指针变量当然也可以指向数组,也可以指向数组元素啦!既然占内存,必然就有对应的指针啦!指向数组元素的指针变量
int a[5], *p;
p = &a[0];
1.C语言中,数组名代表数组的首地址,就是第一个元素的地址。因为上面的赋值等价于:p = a;
2.指向数组元素的指针也可以定义时赋值: int *p = &a[0];或者 int *p = a;
引用数组元素
1.int a[5],*p = &a[1] 如果*p = 10; 则表示对p所指向的数组元素a[1]赋值。等价于a[1] = 10;
2.如果p指向一个数组的元素,则p+1表示指向数组该元素的下一个元素。假设p = &a[0],则p+1表示数组元素a[1]的地址。
结论:不管什么类型的指针+n的时候等价于整型的p+sizeof(type)*n
引用
如果p的初始值是&a[0],那么:p+i和a+i都可以表示元素a[i]的地址;*(p+i)和*(a+i)都表示指针p+i或a+i所指向的数组元素a[i]的值。
总结:引用一个数组元素可以有两种方法:下标法:a[i];指针法:*(p+i).
事例:
void main(){ int a[5] = {1,2,3,4,5}; int *p = a; for (int i = 0; i < 5; i++) { printf("%p:%d ", p+i, *(p+i)); }}
输出结果为:0012FF34:1 0下标0012FF38:2 地址加了40012FF3C:30012FF40:40012FF44:5
现在如果我们换做数组名可以吗?我们试试看:void main(){ int a[5] = {1,2,3,4,5}; int *p = a; for (int i = 0; i < 5; i++) { printf("%p:%d ", a+i, *(a+i)); }}
输出是:0012FF34:10012FF38:20012FF3C:30012FF40:40012FF44:5
我们看到完全是可以的。同理我们也可以这样写:void main(){ int a[5] = {1,2,3,4,5}; for (int *p = a; p < a+5; p++) { printf("%p:%d ", p, *p); }}
输出的结果也是一样的啦!但是这里我们要小心一个错误就是:
不要用数组名做++哦!数组名是一个常量!大家一定要记住!
选择:优先选择用下标法,因为下标法效率不低于指针法而且下标法更可读。
指针做减法:请看下面代码:
大家说,这个程序两地址做减法后结果为多少啊?!大家可能都认为是4.嘿嘿!其实不是啦!是1.因为两地址做减法时最后还要除以sizeof(type)哦!
下面我们来看看如何求数组长度:
大家看清楚了吗?!这样也可以求出!但是大家记住啊。这里只是让我们去理解内存,自己平时写代码不要这样写哦!
大家来看我们今天的最后1个程序事例啦:
唉!怎么回事啊!为什么运行出错啦!郁闷!这是怎么回事的啊?!哦!我们仔细看了下,原因是常量区没有可写权限呀!
那么有没有什么办法让他可以运行啊!其实是可以的啦!只要修改可执行文件的1个标记就可以正常运行啦!我们看看:
我们用二进制方式打开可支持文件:
我们把000228的40改成C0然后保存!再执行可执行文件就可以正常运行啦!我们看改了后:
我们再运行程序输出为:
szMsg:HelLo, pszMsg:HelLo
szMsg:6, pszMsg:4
嘿嘿!成功运行啦!这是什么原因呢?!这是因为啊这个40表示可读不可写。C0呢表示可读可写啦!
补充:软件开发 , C语言 ,