之前写发的那篇指针和数组的文章,有网友评论觉得不是很舒服,我自己看了,觉得很不满意。所以想再写写,尽量把这个东西讲清楚。
#定义为数组,声明为指针
1.c中
#include "stdio.h"
char array[] = "abcd";
2.c中
#include "stdio.h"
extern char *array;
int main(void){
printf("%pn",array);
printf("%sn",(char*)array);
return (0);
}
我们编译一下
![5f150d41bad9f310bd5a7a2d9a5ede46.png](https://i-blog.csdnimg.cn/blog_migrate/8ac3293f2993908f4a5e0d83872d6811.jpeg)
我们运行一下
![b06f37fd129461dce9e2df5c773f9b8c.png](https://i-blog.csdnimg.cn/blog_migrate/7c0e986b10c1ec4d8fe72612c051c468.jpeg)
好了,到了关键的时候了 我们分析一下
声明和定义的区别 声明是只给房产证,但是不给你分房子,实际上没地方住。定义呢,是给你分了房子,也给你发了房产证。
不同的文件编译 编译器是按照一个文件一个文件进行编译的,所以在1.c里面编译器知道这个是一个 char 的字符串。但是在2.c里面,编译器知道这个是一个指针。
数组和指针有什么不同? 数组是一个集合,把同类型的数据放在一个集合里面,数组名代表的是这个集合。就像一个军队的班长,排长等等。
![9940a677aff783e88716586f783b7cdd.png](https://i-blog.csdnimg.cn/blog_migrate/bb3c18c1beed0617ccca4a392e49b5be.jpeg)
有点意思的是,数组的地址和数组首元素的地址值一样,所以才引发了各种有意思的血案。
指针其实就是一个地址,指针变量就是一个可以存相同类型不同值的地址。
![dd5df72a467cdb43ecf017b8ccba95c5.png](https://i-blog.csdnimg.cn/blog_migrate/f6f779a49890afc199dce89ec20dfc33.jpeg)
a存的是一个4byte的地址,这个地址里面存的东西是一个char字符。但是a本身是有房子住的,&a有自己的房子(地址)。
例子代码
#include "stdio.h"
int main()
{
char b = 'b';
char *a = &b;
printf("&a:%pn",&a);
printf("a:%pn",a);
printf("*&a:%pn",*&a);
printf("*a:%cn",*a);
return 0;
}
输出
![fb94b2b7fd3de1607adc7ada3212ca9f.png](https://i-blog.csdnimg.cn/blog_migrate/de0f27528c7b7f2cfad6bc05ffb42dd5.jpeg)
array 定义在1.c中是一个数组,他在1.c里面,政府给他分了房子也发了房产证。 但是在2.c里面,另一个乡政府因为某种原因,只给array发了房产证,而且这个房产证上写的房子地址是1.c里面那个array的地址。 但是写房产证形式的时候,说这个房子的形式是char * array 「声明为指针」这样的形式的。
这样的形式导致什么问题呢? 这样的形式导致 array = "abcd"。就是说abcd的值赋值给了array。 然后我们使用* 去开锁的时候。我们就是 * “abcd” = * 64636261。 但是 64636261 地址并不合法的,如果访问了不合法的地址。那就会出现问题了。就比如政府说这块地才能种菜,你跑到其他地方去种菜了,就可能被抓起来。
贴上一个ASCII表
![6cd74f0df97848cc6a05945efdbe1660.png](https://i-blog.csdnimg.cn/blog_migrate/3bde6fcecdc141422fdbb7e81c60f0c8.jpeg)
我这样解释,还有啥问题的,请留言一起讨论下。
#定义为指针,声明为数组
1.c中
#include "stdio.h"
char *array = "abcdefg";
void p_test(void)
{
printf("%p %pn",array,&array);
printf("%sn",array);
}
2.c中
#include "stdio.h"
extern void p_test(void);
extern char array[];
int main(void){
printf("%pn",array);
printf("%s %.2x%.2x%.2x%.2xn",array,array[0],array[1],array[2],array[3]);
p_test();
return (0);
}
运行一下
![98e05a633cf304df169f8e7e2d075f04.png](https://i-blog.csdnimg.cn/blog_migrate/e662b3adac5e96225788704ea2c3e334.jpeg)
在文件1.c中 array 是一个指针,编译器给这个指针4byte的存储空间。指针的值是 “abcdefg”这个字符串的首地址。这个字符串的存储空间分配在常量区,里面的内容是不能修改的。
在文件2.c中 array 是一个数组,数组的大小是不知道的,但是这个数组的地址是哪里,是我们关心的重点。 从上面打印可以看出来,数组的首地址是等于 1.c文件里面array指针变量的地址。
说了这么多 可以确定一个指针就是指针,数组就是数组。
![5a09ebd17b31bba7768ea3f7a6904804.png](https://i-blog.csdnimg.cn/blog_migrate/40435418f563d0d80b2dce56c06ab8f8.png)