#include <stdio.h>
//Compiler version gcc 6.3.0
int main()
{
char *ptr[10]={"ram","try"};
printf("%s n",ptr); // prints neither string nor character (may be address)(why ?)
printf("%s n",*ptr); // prints string (why ?)
printf("%c n",*ptr[0]); // prints character i.e. r ( why ?)
printf("%s n",ptr[0]); // prints string (understandable)
return 0;
}
为什么 ptr 不打印ram? 为什么 *ptr[0] 不打印字符串?
char *ptr[10]={"ram","try"};
ptr
是一个包含 10 个指针的数组:ptr[0]
, ...自。。。ptr[9]
.数组的每个元素都是一个指针。
ptr[0]
是指向字符串文字"ram"
的指针;ptr[1]
是指向字符串文本"try"
的指针。所有其他 8 个元素都是空指针 (NULL
)。
*ptr[k]
是(字符串ptr[k]
)中的第一个字符,如果不是NULL
printf("%s n",ptr);
既不打印字符串也不打印字符(可能是地址)(为什么?
"%s"
说明符期望一个类型为char*
的值,您正在传递不兼容的 10 个指针(类型char *[10]
)的整个数组,因此您调用了未定义的行为。
printf("%s n",*ptr);
打印字符串(为什么?
*ptr
是ptr[0]
的同义词。它是数组元素之一,类型为char*
。它不是NULL
,所以它按预期工作。
printf("%c n",*ptr[0]);
打印字符,即r(为什么?
*ptr[0]
与ptr[0][0]
(或(ptr[0])[0]
)相同,即...第一个指针的第一个字符(第一个字符串)。它与说明符"%c"
匹配,因此按预期工作。
printf("%s n",ptr[0]);
打印字符串(可以理解)
请参阅上面的*ptr
;它们是相同的。
给定声明
char *ptr[10] = {"ram", "try"};
以下都是正确的:
Expression Type "Decays" to Value
---------- ---- ----------- -----
ptr char *[10] char ** Address of first element (equivalent to &ptr[0]);
not the correct type for the "%s" conversion
specifier in printf
*ptr char * n/a Value of first element;
exactly equivalent to ptr[0]; correct type
for "%s" conversion specifier
ptr[0] char * n/a Same as above
ptr[i] char * n/a Value of the i'th element
*ptr[i] char n/a Value of the first character
of the i'th element
图形:
char * char
+---+ +---+---+---+---+
ptr: | | ptr[0] ----------> |'t'|'r'|'y'| 0 |
+---+ +---+---+---+---+
| | ptr[1] --------+
+---+ | +---+---+---+---+
| | ptr[2] ---||| +-> |'r'|'a'|'m'| 0 |
+---+ +---+---+---+---+
| | ptr[3] ---|||
+---+
...
其中|||
代表NULL
。
printf("%s n",ptr); // prints neither string nor character (may be address)(why ?)
ptr
不是字符串。 它是一个字符串数组。
printf("%s n",ptr[0]); // prints string (understandable)
右。ptr
是一个字符串数组,因此ptr[0]
是这些字符串之一。
printf("%s n",*ptr); // prints string (why ?)
因为ptr
是一个字符串数组,*ptr
与ptr[0]
相同。
printf("%c n",*ptr[0]); // prints character i.e. r ( why ?)
ptr
是一个字符串数组,因此ptr[0]
是其中一个字符串,*ptr[0]
是其中一个字符串中的字符之一。
值得注意的是,这可能很有趣
printf("%cn", ptr[0][0]);
将给出完全相同的结果 - 即打印第一个字符串的第一个字符,就像*ptr[0]
一样。
我们在这里跳舞的,你可能还没有被正确地教过,是有时被称为C 中数组和指针之间的对应关系。 C 中的数组下标是根据指针算法定义的。 对于任何数组a
或指针p
,a[i]
根据定义与*(a + i)
相同,p[i]
根据定义与*(p + i)
相同。
另一个有趣的事实:每当在 C Code 中使用字符串文字时,请考虑添加 const 关键字。因为如果您尝试修改这些字符串之一,这将导致未定义的行为(很可能是分段错误,这反过来意味着您的程序将崩溃)。
这很可能会崩溃:
char *foo = "bar";
foo[1] = 'x'; // Undefined behavior but compiles fine
这将阻止人们编辑数组的内容:
const char *foo = "bar";
foo[1] = 'x'; // Won't compile