考虑一个简单的例子
Eg: const char* letter = "hi how r u";
letter 是一个 const 字符指针,它指向字符串“hi how r u”。现在,当我想打印数据或访问数据时,我应该正确使用*letter
吗?
但是在这种情况下,我不应该只需要在调用 printf 时使用地址吗?
printf("%s",letter);
那么这是为什么呢?
*letter
实际上是一个字符;这是letter
指向的第一个字符。如果您正在对整个字符串进行操作,那么按照惯例,函数将查看该字符以及下一个字符等,直到它们看到一个零 ('\0') 字节。
一般来说,如果你有一个指向一堆元素(即一个数组)的指针,那么指针指向第一个元素,并且不知何故,对这堆元素进行操作的任何代码都需要知道有多少元素。对于char*
,有零约定;对于其他类型的数组,您通常必须将长度作为另一个参数传递。
printf
将指向数据数组的指针作为参数。因此,如果您要显示带有 、 、 等的字符串(一种数组)%s
或带有%d
、%e
、%f
等的数字,请始终传递不带*
. 变量名是指向数组第一个元素的指针,printf
将根据类型(char
是 1 或 2 个字节,int
s 是 4 等)使用简单的指针算法打印数组的每个元素,直到它到达 EOL 或零值。
当然,如果你创建一个指向数组变量的指针,那么你会想用*
. 但这更多的是例外而不是规则。:)
仅仅因为 printf 有这样的签名:int printf(const char* format, ...);
这意味着它期望指向 char 表的指针,它将在内部取消引用。
letter 并不指向整个字符串,而是指向字符串的第一个字符,因此是 char 指针。
当您取消引用指针(使用*
)时,您指的是字符串的第一个字符。
然而,单个字符在打印字符串时非常有用(当打印字符串时),因此它取而代之的是指向第一个元素的指针并递增它的值,打印出取消引用值,直到找到空字符'\0'。
由于这是一个 C++ 问题,同样重要的是要注意您应该真正将字符串存储为安全封装类型std::string
,并尽可能将类型安全 iostreams 存储为:
std::string line="hi how r u";
std::cout << line << std::endl;
%s
打印到第一次\0
看到: http: //msdn.microsoft.com/en-us/library/hf4y5e3w.aspx,%s
是一个字符串格式字段,这里没有什么奇怪的。
printf("%s")
期望地址以通过内存搜索NULL
( \0
) = 字符串结尾。在这种情况下,您只说letter
. printf("%c")
期望值不是地址:printf("%c", *letter);