C/C++指针数组的问题

来源:互联网 发布:制造商采购流程优化 编辑:程序博客网 时间:2024/06/01 08:33

本人小白,本文专门给初学者准备,大神自动跳过。

不喜勿喷,谢谢。

如有错误,请指正,谢谢。


正文:

进来有人问我一些有关于指针的问题。在此我贴出问题

问题如下:

char *msg[5] = {"Thank you","You are"};

mian()

{

printf("%s",msg[0]);

}

问题一:为什么msg[0]可以输出Thank you?

问题二:如果把msg看成是二维数组的名字,那msg[0]不应该是Thank you  的首地址么?

问题三:用%s这个可是可以输出地址里的内容么?

问题四:如果用msg可以输出Thank you 么?*msg呢?


解答:

首先我们来看看我们定义的是什么吧

我们定义的是char *msg[5]; 这是代表我们定义了一个数组,数组名叫msg,数组包含了5个元素,这些元素的类型是char *类型,很明显这些元素是指针

也就是说我们定义了一个指针数组,我们这个数组就是保存了一些地址而已

而且我们在定义的时候,是对这些元素(指针)进行了初始化了的。

msg[0]这个指针存放了“Thank you”这个字符串的首地址,msg[1]这个指针存放了“You are”这个字符串的首地址。


另外我们知道%s是只要我给了一个地址,它就能完整的输出字符串

所以我们在输出的时候传入了一个msg[0],也就是传入了一个地址,这是“Thank you”的首地址。自然而然计算机就能输出完整的Thank you


至于我们能不能将msg看成二维数组的名字呢?我们之后讨论,我们先说最后一个问题

用msg能不能输出Thank you呢?答案是不能

用*msg能不能输出Thank you呢?答案是能

我们来看一下这两者的区别

1. 一个数组的名字在C/C++中,如果没有特别说明,那么它就代表的是一个指针,这个指针指向这串数组的首个元素的地址

那么我们在调用msg的时候,电脑默认我们给了一个msg[0]的地址,也就相当于msg = &msg[0]

所以我们在用%s输出msg的时候,实际上我们就是传入了一个msg[0]的地址,那msg[0]是什么?是指针啊!!!不是字符串啊!!!

所以用msg的时候就不能正确输出

2. 那么第二个呢?*msg又如何呢?

前面一种情况我们已经介绍了msg表示msg[0]的地址。那么当我们使用*msg的时候,它就指向了msg[0]中的内容。因而*msg = msg[0]

那msg[0]存放了什么?存放了“Thank you”的首地址!!!

所以我们在用%s输出*msg的时候是可以正确输出的



最后我们再来看看我们能不能将msg看成是二维数组的名字呢?

我的理解是可以的,虽然不严谨,但是在大部分使用上我认为我可以替换的

这里我们先不讲枯燥的理论知识,我们先来介绍一下如何用动态内存分配去搞出个二维数组

int i;

char **p; //定义一个指向指针的指针(好绕口……)

p = (char **)calloc(5,sizeof(char*)); //先分配最外层的内存,这里我们可以看到我们是分配了5个char*类型的内存,也就是我们打算在这里放5个指针

for(i = 0; i < 5; i++)

(*p) = (char *)calloc(10,sizeof(char));//在分配最内层的内存,也就是我们用来存放“Thank you”的内存

这很经典,仔细观察我们可以发现这和我们上面提到的char *msg[5]很像,不同的是char *msg[5]没有定义最内层的东西,只有最外层的指针。

一个是一维数组,一个是二维数组。虽然定义不一样,但是本质上没啥大区别,我们用它们实现的功能都差不多


所以我说可以看成是二维数组的名字

原创粉丝点击