C语言:字符指针和字符数组的区别

158
考虑:
char amessage[] = "now is the time";
char *pmessage = "now is the time";

我从C程序设计语言,第二版中读到,上述两个语句的作用不同。
我一直认为数组是一个方便的方式来操作指针以存储一些数据,但这显然不是这种情况...在C语言中,数组和指针之间有哪些“非平凡”的区别?

3
我可能记错了,但我想指出可以在指针上使用[]符号,在数组上使用*符号。从代码的角度看,唯一的重要区别是amessage的值不能改变,因此amessage ++会失败(但我相信 *(amessage+1)会成功)。我相信内部还有其他差异,但它们几乎从不真正影响到代码。 - Bill K
2
哦,一般来说(不包括你提到的情况),数组会自动分配内存,而指针则需要你自己分配内存。你的两个变量都应该只是指向在程序加载时分配的内存块。 - Bill K
1
除了K&R(顺便说一句,这是一本很棒的书),我建议你在此期间阅读http://pw2.netcom.com/~tjensen/ptr/cpoint.htm。 - amaterasu
请查看https://dev59.com/WGkw5IYBdhLWcg3wBmCA#10186799。 - Pacerier
由于我们已经有两个关于同一个问题的“规范”FAQ主题,因此将其标记为重复。 - Lundin
可能相关:https://dev59.com/0YXca4cB1Zd3GeqPEixi - Mohit Jain
14个回答

1
上面的答案应该已经回答了你的问题。但我想建议你阅读Sir Dennis Ritchie所著《C语言发展》中的“胚胎C”一段。The Development of C Language

这基本上是一个仅包含链接的回答。其他用户常常会说类似于“虽然这个链接可能回答了问题,但最好在这里包含答案的关键部分,并提供链接作为参考。如果链接页面发生变化,仅有链接的回答可能会失效。”的话。 - undefined

0

对于这行代码: char amessage[] = "now is the time";

编译器将评估对amessage的使用,作为指向包含字符“now is the time”的数组开头的指针。编译器为“now is the time”分配内存,并用字符串“now is the time”初始化它。您知道消息存储在哪里,因为amessage始终指向该消息的开头。amessage可能不会被赋予新值-它不是变量,而是字符串“now is the time”的名称。

这行代码: char *pmessage = "now is the time";

声明一个变量pmessage,它的初始化(给定初始值)为字符串“now is the time”的起始地址。与amessage不同,pmessage可以被赋予新值。在这种情况下,与前面的情况一样,编译器还将“now is the time”存储在内存中的其他位置。 例如,这将导致pmessage指向以“is the time”开头的“i”。 pmessage = pmessage + 4;


-1

这是我为自己总结的数组和指针之间主要区别:

//ATTENTION:
    //Pointer depth 1
     int    marr[]  =  {1,13,25,37,45,56};      // array is implemented as a Pointer TO THE FIRST ARRAY ELEMENT
     int*   pmarr   =  marr;                    // don't use & for assignment, because same pointer depth. Assigning Pointer = Pointer makes them equal. So pmarr points to the first ArrayElement.

     int*   point   = (marr + 1);               // ATTENTION: moves the array-pointer in memory, but by sizeof(TYPE) and not by 1 byte. The steps are equal to the type of the array-elements (here sizeof(int))

    //Pointer depth 2
     int**  ppmarr  = &pmarr;                   // use & because going one level deeper. So use the address of the pointer.

//TYPES
    //array and pointer are different, which can be seen by checking their types
    std::cout << "type of  marr is: "       << typeid(marr).name()          << std::endl;   // int*         so marr  gives a pointer to the first array element
    std::cout << "type of &marr is: "       << typeid(&marr).name()         << std::endl;   // int (*)[6]   so &marr gives a pointer to the whole array

    std::cout << "type of  pmarr is: "      << typeid(pmarr).name()         << std::endl;   // int*         so pmarr  gives a pointer to the first array element
    std::cout << "type of &pmarr is: "      << typeid(&pmarr).name()        << std::endl;   // int**        so &pmarr gives a pointer to to pointer to the first array elelemt. Because & gets us one level deeper.

-2

数组是一个常量指针。你不能更新它的值并使其指向其他地方。 而对于指针,你可以这样做。


数组不是指针,无论是否为const。在许多情况下,数组标识符的类型将隐式地从“T的N元素数组”转换为“指向T的指针”,但这并不意味着数组是指针。 - John Bode
同意了..承认错误..谢谢你的澄清,约翰。 - mkamthan
@JohnBode 我也曾误认为数组是const指针。您能否提供更多资源以消除我的误解? - akashchandrakar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接