这是关于C的一般问题。(我没有很多C编码经验)
所以,如果我有一个以char*
为参数的函数。如何知道它是指向单个char
还是char
数组的指针,因为如果它是char
数组我可以期待\0
但是如果它不是char数组然后我不想搜索\0
。
答案 0 :(得分:8)
参数中的
char*
是指向单个char
还是char
数组的指针?
是
类型为char*
的参数总是指向char
对象的指针(或空指针,不指向任何内容,如果这是调用者传递的内容,则相应的论点)。
它不是指向数组的指针(例如,类型为char(*)[42]
的指针),但访问数组元素的常用方法是通过指向元素类型的指针,而不是整个阵列。为什么?因为实际的指向数组的指针必须始终指定数组的长度(在我的示例中为42
),这是不灵活的,并且不允许相同的函数处理不同长度的数组。
char*
参数可以被视为指向单个char
对象的指针。例如,获取输入字符的函数可能会声明如下:
bool get_next_char(char *c);
这里的想法是函数的结果告诉你它是否成功;实际的输入字符是通过指针“返回”的。 (这是一个人为的例子; <stdio.h>
已经有几个从输入中读取字符的函数,它们不使用这种机制。)
比较strlen
函数,它计算字符串的长度:
size_t strlen(const char *s);
s
指向char
的数组的第一个元素;在内部,strlen
使用该指针遍历数组,查找终止'\0'
字符。
忽略const
,这两个函数的char*
参数之间没有真正的区别。实际上,C没有很好的方法可以区分这些情况:一个指向单个对象的指针与一个指向数组第一个元素的指针。
它确实有坏方式来区分。例如,strlen
可以声明为:
size_t strlen(const char s[]);
但是C根本没有数组类型的参数。参数声明const char s[]
被“调整”为const char *s
;它意味着完全相同的事情。你甚至可以为看起来像数组参数的东西声明一个长度:
void foo(char s[42]);
它将被悄然忽略;以上内容实际上与以下内容完全相同:
void foo(char *s);
[42]
可能有一些文档值,但注释具有相同的值 - 并且就编译器而言具有相同的意义。
指向单个对象的指针和指向数组第一个元素的指针之间的任何区别都必须由程序员进行,最好是在函数的文档中。
此外,这种机制不会让函数知道数组有多长。特别是对于char*
指针,通常使用空字符'\0'
作为字符串结尾的标记 - 这意味着调用者有责任确保该标记实际存在。否则,您可以将长度作为单独的参数传递,可能是size_t
类型。或者你可以使用你喜欢的任何其他机制,只要一切都是一致的。
...因为如果它是
char
数组我可以期待\0
......
不,你不能,至少不一定。 char*
可以很容易地指向char
数组的第一个元素,它不会被'\0'
字符终止(即,不包含字符串)。如果你愿意,可以强加这样的要求。对字符串进行操作的标准库函数强加了该要求 - 但它们并未强制执行。例如,如果将指向未终止的数组的指针传递给strlen
,则行为未定义。
推荐阅读:comp.lang.c FAQ的第6部分。
答案 1 :(得分:6)
您无法确定指针引用的字节数。你需要自己跟踪这个。
答案 2 :(得分:1)
char数组可能 NOT 以\0
终止,在这种情况下,您需要知道数组的长度。此外,数组的长度可能为1,在这种情况下,您有一个字符没有终止\0
。
关于C
的好处是您可以定义有关数据结构的详细信息,因此 NOT 仅限于始终以\0
结尾的char数组。< / p>
用于描述C数据结构的一些术语是同义词。例如,数组是连续的数据元素系列,字符数组是字符串,字符串可以用空字符(\0
)终止。