关于复杂声明
代码如下,这个本来是一道课后题,用二维指针数组的方法我可以做出来,但是想知道如果只能通过下面的方法,应该如何才能正确输出?我编译的时候一直提示我14行的位置:warning: initialization from incompatible pointer type
我这里定义的p是 (存放(存放(字符类型指针)的数组)的数组,感觉应该没什么问题啊...但是输出却是乱码...
不太能理解,麻烦大家帮忙看看。
#include <stdio.h>
void main()
{
char *line1 = {"########","####"," ###### ","## ##"," ###### "};
char *line2 = {"## "," ## ","## ##","## ##","## ##"};
char *line3 = {"## "," ## ","## ","## ##","## "};
char *line4 = {"######"," ## "," ###### ","#########","## "};
char *line5 = {"## "," ## "," ##","## ##","## "};
char *line6 = {"## "," ## ","## ##","## ##","## ##"};
char *line7 = {"## ","####"," ###### ","## ##"," ###### "};
char *(p) = {line1,line2,line3,line4,line5,line6,line7};
printf("%s",p);
}
本帖最后由 Croper 于 2019-5-14 20:09 编辑
既然line1 ,line2都是数组,p,p也是数组,那么原程序不是在拿数组给数组赋值么,C语言显然不允许这么写。
非要这样写请使用二重指针数组char **p = {line1,line2,line3,line4,line5,line6,line7};
话说你为什么总是问这种纠结问题,有这个功夫都能学很多东西了。到时候再回来看这些不更好么 本帖最后由 YiMingC 于 2019-5-14 21:51 编辑
Croper 发表于 2019-5-14 19:55
既然line1 ,line2都是数组,p,p也是数组,那么原程序不是在拿数组给数组赋值么,C语言显然不允许这么 ...
原来如此,您给出的定义我可以理解了。感谢~
但是关于您说的“那么原程序不是在拿数组给数组赋值么”是体现在不能把数组作为新数组元素吗?数组作为数组元素的时候应该看成类指针?我刚刚试了试确实会有警告:从不兼容的指针类型初始化
我老觉得自己学的不够扎实,数组和指针这些东西不掌握彻底怕自己以后全乱套了...麻烦您了~ 本帖最后由 Croper 于 2019-5-14 22:01 编辑
YiMingC 发表于 2019-5-14 21:31
原来如此,您给出的定义我可以理解了。感谢~
但是关于您说的“那么原程序不是在拿数组给数组赋值么 ...
非要说的话p是个指针的二维数组,你是在给这个长度为35的数组的前7个元素赋初始值。解出来的p其实是line1的地址,也是line1第一个指针的地址,但是它的类型是(char*),所以不能直接解引用,把类型转换成(char**)再接引用应该就能得到"#######"了;
然后关于这些复杂的定义一般都是typedef掉的,谁有空去看一堆星星框框的。。 Croper 发表于 2019-5-14 21:57
非要说的话p是个指针的二维数组,你是在给这个长度为35的数组的前7个元素赋初始值。解出来的p其 ...
解出来的p的类型确实是char*,但是字符串在打印的时候不是就是给一个地址就可以了吗...{:5_99:} 本帖最后由 Croper 于 2019-5-14 22:17 编辑
又来了。。
p的类型是char*,但实际的值是指针的地址,不是指针本身。。明白么
然后你如果直接解引用,得到的值是这个指针的最后一个字节,而不是整个指针。所以需要进行类型转换,
p<====>list1
char* char**
*p <====> *(char*)list1
char(只有1个字节) char(只有1个字节)
*(char**)p <=====> *list1
char*(4个字节) char*(4个字节)
明白了么
不明白也没关系,反正也没啥用。。
话说c++里再来个引用,然后指针的引用,引用的指针,指针的数组的引用,岂不是要炸。。(小声) 这样也可以
另外,不要纠结这类问题了
p是一个数组,有7个元素,每一个元素都是一个指针,这个指针指向一个数组,指向的这个数组有5个元素,每一个元素都是一个指针,这个指针指向char
#include <stdio.h>
int main(void)
{
char *line1 = {"########","####"," ###### ","## ##"," ###### "};
char *line2 = {"## "," ## ","## ##","## ##","## ##"};
char *line3 = {"## "," ## ","## ","## ##","## "};
char *line4 = {"######"," ## "," ###### ","#########","## "};
char *line5 = {"## "," ## "," ##","## ##","## "};
char *line6 = {"## "," ## ","## ##","## ##","## ##"};
char *line7 = {"## ","####"," ###### ","## ##"," ###### "};
char *(*p) = {&line1, &line2, &line3, &line4, &line5, &line6, &line7};
printf("%s\n", (*p));
return 0;
}
本帖最后由 YiMingC 于 2019-5-14 22:39 编辑
Croper 发表于 2019-5-14 22:11
又来了。。
p的类型是char*,但实际的值是指针的地址,不是指针本身。。明白么
然后你如果直接解引 ...
但是它的类型是(char*),所以不能直接解引用,
把类型转换成(char**)再接引用应该就能得到"#######"了;
这段不是太理解...
您说的p是指针的地址我能理解,把他解引用不就是指针变量存放的地址吗...最后要得到的不就是这个地址吗...char**类型是指向指针的指针吗...{:5_107:} 人造人 发表于 2019-5-14 22:17
这样也可以
另外,不要纠结这类问题了
这个我可以理解,但是类型转换的那个有点蒙圈...这次纠结完应该能有一段不纠结了{:5_111:} Croper 发表于 2019-5-14 22:11
又来了。。
p的类型是char*,但实际的值是指针的地址,不是指针本身。。明白么
然后你如果直接解引 ...
这个4字节是哪里来的啊...而且为什么直接解引用会是最后一个字节啊 (问题一个接一个){:10_266:} 本帖最后由 Croper 于 2019-5-14 23:15 编辑
您说的p是指针的地址我能理解,把他解引用不就是指针变量存放的地址吗
不是,
比如说这里有一堆数据
46 69 73 6863 00 00 00
然后有一个指针指向第一个字节,然后对这个指针解引用,你会得到什么?
结果是:无法确定
因为这要视指针类型而定,
如果这是一个char* 指针,那么得到的值为0x46(F)
如果这是一个int* 指针,那么得到的值为0x68736946
如果这是一个long long*指针,那么得到的值为0x0000006368736946
如果这是一个char**指针,那么得到的值也为0x68736946,然后程序会把这个值看成一个地址,你可以继续对这个地址解引用
再说回来,你写出类似于printf("%s",*p);这个语句时,这里隐藏了一个类型转换,写全是这样,printf("%s",(char*)*p);
于是,你就把一个一个指针的最后一个字节前面扩充0的值当成了指针原来的值,最后当然没法得到你想要的结果 Croper 发表于 2019-5-14 23:00
不是,
比如说这里有一堆数据
好吧,基本上理解了,差不多先够用了,谢谢啦{:10_250:}
页:
[1]