我在 C 中有以下代码
#include <stdio.h>
char *gstr[] = { "Hello", "World" };
void func(char str[][8]) {
printf("%p\n", (void *)str);
printf("%p\n", (void *)(str + 1));
printf("%s\n", *(str + 1));
}
int main(void) {
printf("%p\n", (void *)gstr);
printf("%p\n", (void *)(gstr + 1));
printf("%s\n", *(gstr + 1));
printf("Calling Function\n");
func(gstr);
return 0;
}
以下是输出
0x556f11ddd010
0x556f11ddd018
World
Calling Function
0x556f11ddd010
0x556f11ddd018
$��oU
我不明白为什么函数 printf("%s\n", *(str+1));
中的 func
不打印字符串 world
。
答案 0 :(得分:3)
char *gstr[] = {"Hello", "World"};
将 gstr
声明为指向 char
的指针数组。
就其本身而言,char str[][8]
将 str
声明为一个由 8 个 char
组成的数组。但是,作为函数参数,它会自动从数组调整为指针:它声明 str
为指向八位 char
数组的指针。
指向数组的指针与指向数组的指针不同。
您的编译器应该警告您,gstr
中的 func(gstr)
类型与 void func(char str[][8])
中的参数类型不兼容。注意来自编译器的消息。
要正确地将 gstr
传递给 func
,请将 func
的声明更改为 func(char *str[])
或等效的 func(char **str)
。
func(gstr)
将 gstr
的第一个元素的地址传递给函数。由于 gstr
是一个指针数组,它的第一个元素的地址是一个指针的地址(即指向 "Hello"
的第一个字符的指针)。
在 func
中,该函数需要一个指向 8 个 char
数组的指针。如果它使用为此给出的地址,则它指向一个指针而不是一个包含 8 个 char
的数组。将它传递给 printf
尝试打印表示指针的字节,就好像它们是一个字符串一样。
答案 1 :(得分:1)
您可以编译下面的代码以查看输出。
monthIndex = i mod 12
nameIndex = i mod 16
#include <stdio.h>
char *gstr[] = {"Hello", "World"};
void func(char str[][8]) {
printf("%p\n", (void*) str);
printf("%p\n", (void*) *str);
printf("%p\n", (void*) (str+1));
printf("%p\n", (void*) *(str+1));
printf("%s\n", *(str+1));
}
int main(void) {
printf("%p\n", (void *) gstr);
printf("%p\n", (void *) *gstr);
printf("%p\n", (void*) (gstr+1));
printf("%p\n", (void*) *(gstr+1));
printf("%s\n", *(gstr+1));
printf("Calling Function\n");
func(gstr);
return 0;
}
编译器知道 gstr 是一个指针数组,因此在函数 0x100402010
0x100403000
0x100402018
0x100403006
World
Calling Function
0x100402010
0x100402010
0x100402018
0x100402018
0@
中,main
处的对象将被解释为 gstr + 1
并得到预期结果。>
但是在函数 char*
中,func
处的字节将被解释为 str + 1
,并且您知道它将返回此对象的第一个地址,即 char [8]
< /p>