参数中的"char*"是指向单个char还是char数组的指针?

AdR*_*oiT 3 c pointers

这是一个关于C的一般性问题.(我没有很多用C语言编写的经验)所以,如果我有一个函数char*作为参数.如何知道它是指向单个数组char还是char数组的指针,因为如果它是一个char数组我可以期待\0但是如果它不是一个char数组那么我就不想搜索了\0.

Kei*_*son 8

char*在争论一个指向单一charchar数组?

是.

类型的参数char*总是一个指向char对象(或一个空指针,不指向任何东西,如果这就是调用者传递的相应参数).

它不是指向数组的指针(例如,类型的指针char(*)[42]),但访问数组元素的常用方法是通过指向元素类型的指针,而不是指向整个数组.为什么?因为实际的指向数组的指针必须始终指定数组的长度(42在我的示例中),这是不灵活的,并且不允许相同的函数处理不同长度的数组.

char*参数可以被视为只是作为一个指针到单个char对象.例如,获取输入字符的函数可能会声明如下:

bool get_next_char(char *c);
Run Code Online (Sandbox Code Playgroud)

这里的想法是函数的结果告诉你它是否成功; 实际的输入字符是通过指针"返回"的.(这是一个人为的例子; <stdio.h>已经有几个从输入中读取字符的函数,它们不使用这种机制.)

比较strlen函数,它计算字符串的长度:

size_t strlen(const char *s);
Run Code Online (Sandbox Code Playgroud)

s指向一个的第一个元素阵列char; 在内部,strlen使用该指针遍历数组,查找终止'\0'字符.

忽略const,char*这两个函数的参数之间没有真正的区别.实际上,C没有很好的方法可以区分这些情况:一个指向单个对象的指针与一个指向数组第一个元素的指针.

它确实有一种糟糕的方式来区分它.例如,strlen可以声明为:

size_t strlen(const char s[]);
Run Code Online (Sandbox Code Playgroud)

但是C根本没有数组类型的参数.参数声明const char s[]被"调整"为const char *s; 它意味着完全相同的事情.你甚至可以为看起来像数组参数的东西声明一个长度:

void foo(char s[42]);
Run Code Online (Sandbox Code Playgroud)

它将被悄然忽略; 以上内容实际上与以下内容完全相同:

void foo(char *s);
Run Code Online (Sandbox Code Playgroud)

[42]可能有一些文档的价值,但注释具有相同的价值-同样的意义,只要编译器而言.

指向单个对象的指针和指向数组第一个元素的指针之间的任何区别都必须由程序员进行,最好是在函数的文档中.

此外,这种机制不会让函数知道数组有多长.char*特别是对于指针,通常使用空字符'\0'作为字符串结尾的标记 - 这意味着调用者有责任确保该标记实际存在.否则,您可以将长度作为单独的参数传递,可能是类型size_t.或者你可以使用你喜欢的任何其他机制,只要一切都是一致的.

...因为如果它是一个char数组我可以期待\0...

不,你不能,至少不一定.A char*可以很容易地指向未被字符终止char数组的第一个元素(即,不包含字符串).如果你愿意,可以强加这样的要求.对字符串进行操作的标准库函数强加了该要求 - 但它们并未强制执行.例如,如果将指针传递给未终止的数组,则行为未定义.'\0'strlen

推荐阅读:comp.lang.c FAQ的第6部分.


alk*_*alk 6

您无法确定指针引用的字节数.你需要自己跟踪这个.