The difference between char * and char[]
我读了很多关于它的文章和问题,读了很多答案,但仍然很难理解它们的区别,以及什么时候应该使用什么?
我认为需要存储数据时应该使用char*,因为它是动态的,所以您不知道它的大小。另外,我不确定我是否是对的,但根据我所了解的,如果您声明一个char*并为它指定如下文本:char*ch="嗨";它是一个常数,你不能改变它,如果你真的尝试改变它,你只需要把ch指向另一个分配的内存空间来保存新的字符串?如果这样写:char ch=malloc(20);然后您可以更改值如果你这样做:char ch[]="嗨";CHCH=CH;您也可以更改这些值,因为您指向数组,而数组指向ch[0]?
所有这些都是用粗体字写的,这是我从阅读中理解的,尽管我可能对我刚才说的大部分内容都是错的,这就是为什么我需要一个非常好和简单的解释,这样我就可以一次又一次地理解不同之处,以及什么时候应该使用什么。
编辑:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
最直接的答案是:
The difference here is that
1 char *s ="Hello world";will place Hello world in the read-only parts of the memory and making
s a pointer to that, making any writing operation on this memory
illegal. While doing:
1 char s[] ="Hello world";puts the literal string in read-only memory and copies the string to
newly allocated memory on the stack. Thus making
1 s[0] = 'J';legal.
一个更冗长的解释将包括内存存储在哪个段,以及分配了多少内存:
1 2 3 4 5 6 7 | Example: Allocation Type: Read/Write: Storage Location: Memory Used (Bytes): =========================================================================================================== const char* str ="Stack"; Static Read-only Code segment 6 (5 chars plus '\0') char* str ="Stack"; Static Read-only Code segment 6 (5 chars plus '\0') char* str = malloc(...); Dynamic Read-write Heap Amount passed to malloc char str[] ="Stack"; Static Read-write Stack 6 (5 chars plus '\0') char strGlobal[10] ="Global"; Static Read-write Data Segment (R/W) 10 |
工具书类
编辑
为了解决问题中的编辑和随问题一起发布的评论,我在您的解决方案中添加了注释:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #include <stdio.h> int main() { char ch[] ="Hello"; /* OK; Creating an array of 6 bytes to store * 'H', 'e', 'l', 'l', 'o', '\0' */ char *p1 = ch; /* OK; Creating a pointer that points to the *"Hello" string. */ char *p2 = p1; /* OK; Creating a second pointer that also * points to the"Hello" string. */ char *p3 = *p1; /* BAD; You are assigning an actual character * (*p1) to a pointer-to-char variable (p3); * It might be more intuitive if written in * 2 lines: * char* p3; * p3 = *p1; //BAD */ printf("ch : %s ", ch); /* OK */ printf("p1 address [%d] value is %s ", p1, *p1); /* Bad format specifiers */ printf("p2 address [%d] value is %s ", p2, *p2); /* Bad format specifiers */ printf("p3 address [%d] value is %s ", p3, *p3); /* Bad format specifiers */ return 0; } |
所以,三个主要的错误。
实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | #include <stdio.h> int main(void) { char c = 'H'; // A character char* pC = &c; // A pointer to a single character; IS NOT A STRING char cArray[] = { 'H', 'e', 'l', 'l', 'o' }; // An array of characters; IS NOT A STRING char cString[] = { 'H', 'e', 'l', 'l', 'o', '\0' }; // An array of characters with a trailing NULL charcter; THIS IS A C-STYLE STRING // You could also replace the '\0' with 0 or NULL, ie: //char cString[] = { 'H', 'e', 'l', 'l', 'o', (char)0 }; //char cString[] = { 'H', 'e', 'l', 'l', 'o', NULL }; const char* myString ="Hello world!"; // A C-style string; the '\0' is added automatically for you printf("%s ", myString); // OK; Prints a string stored in a variable printf("%s ","Ducks rock!"); // OK; Prints a string LITERAL; Notice the use of DOUBLE quotes,"" printf("%s ", cString); // OK; Prints a string stored in a variable printf("%c ", c); // OK; Prints a character printf("%c ", *pC); // OK; Prints a character stored in the location that pC points to printf("%c ", 'J'); // OK; Prints a character LITERAL; Notice the use of SINGLE quotes, ' ' /* The following are wrong, and your compiler should be spitting out warnings or even not allowing the * code to compile. They will almost certainly cause a segmentation fault. Uncomment them if you * want to see for yourself by removing the"#if 0" and"#endif" statements. */ #if 0 printf("%s ", c); // WRONG; Is attempting to print a character as a string, similar // to what you are doing. printf("%s ", *pC); // WRONG; Is attempting to print a character as a string. This is // EXACTLY what you are doing. printf("%s ", cArray); // WRONG; cArray is a character ARRAY, not a C-style string, which is just // a character array with the '\0' character at the end; printf // will continue printing whatever follows the end of the string (ie: // random memory, junk, etc) until it encounters a zero stored in memory. #endif return 0; } |
代码列表-建议的解决方案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #include <stdio.h> int main() { char ch[] ="Hello"; /* OK; Creating an array of 6 bytes to store * 'H', 'e', 'l', 'l', 'o', '\0' */ char *p1 = ch; /* OK; Creating a pointer that points to the *"Hello" string. */ char *p2 = p1; /* OK; Creating a second pointer that also * points to the"Hello" string. */ char *p3 = p1; /* OK; Assigning a pointer-to-char to a * pointer-to-char variables. */ printf("ch : %s ", ch); /* OK */ printf("p1 address [%p] value is %s ", p1, p1); /* Fixed format specifiers */ printf("p2 address [%p] value is %s ", p2, p2); /* Fixed format specifiers */ printf("p3 address [%p] value is %s ", p3, p3); /* Fixed format specifiers */ return 0; } |
样本输出
1 2 3 4 | ch : Hello p1 address [0x7fff58e45666] value is Hello p2 address [0x7fff58e45666] value is Hello p3 address [0x7fff58e45666] value is Hello |