c语言 - 如果字符 *ptr[10]={ "ram" , "try" } 那么 ptr ,*ptr , *ptr[0] , ptr[0] 之间有什么区别,如果都给定 printf 函数中使用的四种


#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);打印字符串(为什么?

*ptrptr[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是一个字符串数组,*ptrptr[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或指针pa[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

相关内容

最新更新