char * 和 char[] 的区别 [重复]
Posted
技术标签:
【中文标题】char * 和 char[] 的区别 [重复]【英文标题】:The difference between char * and char[] [duplicate] 【发布时间】:2014-10-28 11:14:41 【问题描述】:我已经阅读了很多关于它的主题和问题并阅读了很多答案,但仍然难以理解差异以及何时应该使用什么?
我认为当您需要存储数据并且您不知道它的大小时应该使用 char*,因为它是动态的。 另外,我不确定我是否正确,但根据我的理解,如果您声明一个 char* 并为其分配一个像这样的文字: 字符 *ch = "嗨"; 这是一个您无法更改的常量,如果您尝试更改它,您只需将 ch 指向另一个分配的存储新字符串的内存空间? 如果这样写: char ch = malloc(20); 然后你可以改变值 如果你这样做: char ch[] = "你好"; 字符 pch = ch; 您也可以更改值,因为您指向数组并且数组指向 ch[0] ?
所有用粗体字写的都是我的阅读理解,虽然我可能对我刚才所说的大部分内容都错了,这就是为什么我需要一个非常好的和简单的解释,这样我才能一劳永逸地理解差异以及什么时候应该使用什么。
编辑:
#include <stdio.h>
main()
char ch[] = "Hello";
char *p1 = ch;
char *p2 = p1;
char *p3 = *p1;
printf("ch : %s\n", ch);
printf("p1 address [%d] value is %s\n", p1, *p1);
printf("p2 address [%d] value is %s\n", p2, *p2);
printf("p3 address [%d] value is %s\n", p3, *p3);
return 0;
【问题讨论】:
阅读comp.lang.c FAQ的第6部分。 【参考方案1】:最直接的答案是:
这里的区别在于
char *s = "Hello world";
将Hello world放置在内存的只读部分并制作 s 一个指向它的指针,在这个内存上进行任何写操作 非法的。做的时候:
char s[] = "Hello world";
将文字字符串放入只读内存并将字符串复制到 堆栈上新分配的内存。从而使
s[0] = 'J';
合法的。
更冗长的解释包括内存存储在哪些段中,以及分配了多少内存:
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
参考文献
-
C 中 char s[] 和 char *s 有什么区别?,访问时间:2014-09-03,
<https://***.com/questions/1704407/what-is-the-difference-between-char-s-and-char-s-in-c>
声明的字符串和分配的字符串的区别,访问时间:2014-09-03,<https://***.com/questions/16021454/difference-between-declared-string-and-allocated-string>
编辑
为了解决问题中的编辑以及随之而来的评论,我在您的解决方案中添加了注释:
#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\n", ch); /* OK */
printf("p1 address [%d] value is %s\n", p1, *p1); /* Bad format specifiers */
printf("p2 address [%d] value is %s\n", p2, *p2); /* Bad format specifiers */
printf("p3 address [%d] value is %s\n", p3, *p3); /* Bad format specifiers */
return 0;
所以,三个主要错误。
-
您正在将
char
值分配给 pointer-to-char
变量。你的编译器应该警告你这一点。 (char *p3 = *p1
)。
根据您的编译器,您可能必须使用指针%p
格式说明符而不是%d
(整数)格式说明符来打印地址。
您正在使用带有char
数据类型的字符串%s
说明符(即:printf("%s", 'c')
是错误的)。如果要打印单个字符,则使用%c
格式说明符,并且匹配的参数应该是一个字符(即:'c'、char b 等)。如果要打印整个字符串,则使用 %s
格式说明符,并且参数是 pointer-to-char。
示例
#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\n", myString); // OK; Prints a string stored in a variable
printf("%s\n", "Ducks rock!"); // OK; Prints a string LITERAL; Notice the use of DOUBLE quotes, " "
printf("%s\n", cString); // OK; Prints a string stored in a variable
printf("%c\n", c); // OK; Prints a character
printf("%c\n", *pC); // OK; Prints a character stored in the location that pC points to
printf("%c\n", '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\n", c); // WRONG; Is attempting to print a character as a string, similar
// to what you are doing.
printf("%s\n", *pC); // WRONG; Is attempting to print a character as a string. This is
// EXACTLY what you are doing.
printf("%s\n", 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;
代码清单 - 建议的解决方案
#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\n", ch); /* OK */
printf("p1 address [%p] value is %s\n", p1, p1); /* Fixed format specifiers */
printf("p2 address [%p] value is %s\n", p2, p2); /* Fixed format specifiers */
printf("p3 address [%p] value is %s\n", p3, p3); /* Fixed format specifiers */
return 0;
样本输出
ch : Hello
p1 address [0x7fff58e45666] value is Hello
p2 address [0x7fff58e45666] value is Hello
p3 address [0x7fff58e45666] value is Hello
【讨论】:
从副本中逐字复制粘贴的目的是什么? @OliCharlesworth OP 注意到他/她已经浏览了现有的答案,所以我拿了一个特别好的答案,并用一个略带切线的答案对其进行了详细说明。也引用了消息来源。 @Dogbert 我试过做一些测试并制作了一个测试程序,但它崩溃了你能指出我为什么吗?我已经编辑了我的原始帖子 @AALC 我已经对您的编辑做出了彻底的回应。它应该清楚并解释您的程序失败的原因,并提供解决方案。 @Dogbert 很棒的解释,对我帮助很大,谢谢 :)以上是关于char * 和 char[] 的区别 [重复]的主要内容,如果未能解决你的问题,请参考以下文章