【发布时间】:2019-01-11 09:58:57
【问题描述】:
一些示例代码:
#include <stdio.h>
void func0(char *x)
{
printf("func0, %s, %zu\n", x, sizeof(x));
}
//for comparison with func0
void func1(char **x)
{
printf("func1, %s, %zu\n", *x, sizeof(*x));
}
int main()
{
char x[10] = "hello";
printf("%s, %zu, %zu, %zu\n", x, sizeof(x), sizeof(*x), sizeof("hello"));
func0(x);
func1(&x);
return 0;
}
对于 func1()(用于与 func0 进行比较),存在“警告:不兼容的指针类型将 'char (*)[10]' 传递给 'char **' 类型的参数”和“分段错误”错误。
但是对于 func0(),'char [10]' 类型不是转换为 'char *' 吗?如果是这样,printf("%s") 怎么还能打印出“hello”?如func0()的输出所示:
hello, 10, 1, 6
func0, hello, 8
长度信息(即char[N]的N)是否传递给func0?
func0 中的 x 和 func1 中的 *x 有什么区别?它们不都是指向字符的地址吗?
非常感谢。
[编辑] 非常感谢您的详细回答!
让我总结一下 func1() 的警告和错误。
char x[10] = "hello";
&x 的类型是 char (*)[10],它是指向数组的指针,而不是指向指针的指针(例如 char **)。因此发出警告。
x 已经是地址(指向字符串),只能取实际内存空间的地址。 &x 不是 x 的地址。 **x in func1(): 试图从非法地址(本例中的“H”值?)读取,因此出现分段错误。
额外的问题是:
使用 &x 的用例是什么(例如 char (*) [N])?
我看到了 x 和 &x、char * / char[N] 与 char (*) [N] 之间的区别,但我无法确定必须使用 char(*) [N] 的情况。 x 和 &x 毕竟是同一个地址。
【问题讨论】:
-
C 中的 char* 字符串以零结尾。这意味着 printf 语句不知道字符串的长度,而只是打印每个字符,直到找到的第一个零字符。
-
@Adder,啊,有道理。那为什么func1中的printf会失败呢?
-
char **x是一个指向指针数组(实际上是你的字符串)的指针。使用它的值是&(*x),它就是x->printf("func1, %s, %lu\n", x, sizeof(x)); -
@Hearner:
char **x不是指向指针数组的指针。它是一个指向char的指针。换句话说,它的类型不包括任何类型的数组。在指向的位置可能有一个指针数组,但这不是char **x类型的一部分。