之前写发的那篇指针和数组的文章,有网友评论觉得不是很舒服,我自己看了,觉得很不满意。所以想再写写,尽量把这个东西讲清楚。
#定义为数组,声明为指针
1.c中
#include "stdio.h"
char array[] = "abcd";
2.c中
#include "stdio.h"
extern char *array;
int main(void){printf("%p\n",array);printf("%s\n",(char*)array);return (0);
}
我们编译一下
我们运行一下
好了,到了关键的时候了 我们分析一下
声明和定义的区别
声明是只给房产证,但是不给你分房子,实际上没地方住。定义呢,是给你分了房子,也给你发了房产证。
不同的文件编译 编译器是按照一个文件一个文件进行编译的,所以在1.c里面编译器知道这个是一个 char 的字符串。但是在2.c里面,编译器知道这个是一个指针。
数组和指针有什么不同?
数组是一个集合,把同类型的数据放在一个集合里面,数组名代表的是这个集合。就像一个军队的班长,排长等等。有点意思的是,数组的地址和数组首元素的地址值一样,所以才引发了各种有意思的血案。
指针其实就是一个地址,指针变量就是一个可以存相同类型不同值的地址。解释:
a里面保存的是一个4byte的地址,这个地址里面指向的是一个char字符。但是a本身是有房子住的,&a有自己的房子(地址)。
我这里说指向,而不是说保存,我觉得指向更能说明问题,也可以说保存,内存地址保存的东西是一个char值。看个人理解的不同吧。
例子代码
#include "stdio.h"int main()
{char b = 'b';char *a = &b;printf("&a:%p\n",&a);printf("a:%p\n",a);printf("*&a:%p\n",*&a);printf("*a:%c\n",*a);return 0;
}
输出
array 定义在1.c中是一个数组,他在1.c里面,政府给他分了房子也发了房产证。但是在2.c里面,另一个乡政府因为某种原因,只给array发了房产证,而且这个房产证上写的房子地址是1.c里面那个array的地址。但是写房产证形式的时候,说这个房子的形式是char * array 「声明为指针」这样的形式的。
这样的形式导致什么问题呢?
这样的形式导致 array = "abcd"。就是说abcd的值「地址」赋值给了array。然后我们使用* 去开锁的时候。我们就是 * “abcd” = * 64636261。但是 64636261 地址并不合法的,如果访问了不合法的地址。那就会出现问题了。就比如政府说这块地才能种菜,你跑到其他地方去种菜了,就可能被抓起来。
贴上一个ASCII表
我这样解释,还有啥问题的,请留言一起讨论下。
#定义为指针,声明为数组
1.c中
#include "stdio.h"
char *array = "abcdefg";void p_test(void)
{printf("%p %p\n",array,&array);printf("%s\n",array);
}
2.c中
#include "stdio.h"
extern void p_test(void);
extern char array[];
int main(void){printf("%p\n",array);printf("%s %.2x%.2x%.2x%.2x\n",array,array[0],array[1],array[2],array[3]);p_test();return (0);
}
运行一下
在文件1.c中 array 是一个指针,编译器给这个指针4byte的存储空间。指针的值是 “abcdefg”这个字符串的首地址。这个字符串的存储空间分配在常量区,里面的内容是不能修改的。
在文件2.c中 array 是一个数组,数组的大小是不知道的,但是这个数组的地址是哪里,是我们关心的重点。从上面打印可以看出来,数组的首地址是等于 1.c文件里面array指针变量的地址。
说了这么多 可以确定一个事情是指针就是指针,数组就是数组。有时候把数组当指针用,或者把指针当数组用,都是穿着狼皮的人。一定要注意,小心被咬死。
数组是一块内存区域的集合。说指针的时候,我们一般指指针变量,只有指针变量才体现指针的灵活性。当指针不能变的时候,一般都是做函数参数,避免被修改。
回复「 篮球的大肚子」进入技术群聊
回复「1024」获取1000G学习资料