ede*_*ded 9 c string pointers compiler-errors
我刚开始学习C并发现了一些关于字符串指针和字符串(char数组)的混淆.任何人都可以帮我清醒一下吗?
// source code
char name[10] = "Apple";
char *name2 = "Orange";
printf("the address of name: %p\n", name);
printf("the address of the first letter of name: %p\n", &(*name));
printf("first letter of name using pointer way: %c\n", *name);
printf("first letter of name using array way: %c\n", name[0]);
printf("---------------------------------------------\n");
printf("the address of name2: %p\n", name2);
printf("the address of the first letter of name2: %p\n", &(*name2));
printf("first letter of name2 using pointer way: %c\n", *name2);
printf("first letter of name2 using array way: %c\n", name2[0]);
// output
the address of name: 0x7fff1ee0ad50
the address of the first letter of name: 0x7fff1ee0ad50
first letter of name using pointer way: A
first letter of name using array way: A
---------------------------------------------
the address of name2: 0x4007b8
the address of the first letter of name2: 0x4007b8
first letter of name2 using pointer way: O
first letter of name2 using array way: O
Run Code Online (Sandbox Code Playgroud)
所以我假设name和name2都指向他们自己的第一个字母的地址.然后我的困惑是(见下面的代码)
//code
char *name3; // initialize a char pointer
name3 = "Apple"; // point to the first letter of "Apple", no compile error
char name4[10]; // reserve 10 space in the memory
name4 = "Apple"; // compile errorrrr!!!!!!!!!!
Run Code Online (Sandbox Code Playgroud)
我创建一个名为name2的char指针和指向"Apple"的第一个字母的name2指针,这很好,然后我创建另一个char数组并在内存中分配10个空格.然后尝试使用name4,这是一个指向"Apple"第一个字母的地址.结果,我收到了编译错误.
我对这种编程语言感到非常沮丧.有时他们的工作方式相同.但有时他们没有.任何人都可以解释原因,如果我真的想在分隔行中创建字符串或字符数组.我怎么能这样做?
非常感谢...
您可以在声明数组时初始化数组,如下所示:
int n[5] = { 0, 1, 2, 3, 4 };
char c[5] = { 'd', 'a', 't', 'a', '\0' };
Run Code Online (Sandbox Code Playgroud)
但由于我们通常将char数组视为字符串,因此C允许特殊情况:
char c[5] = "data"; // Terminating null character is added.
Run Code Online (Sandbox Code Playgroud)
但是,一旦声明了数组,就无法重新分配它.为什么?考虑像
char *my_str = "foo"; // Declare and initialize a char pointer.
my_str = "bar"; // Change its value.
Run Code Online (Sandbox Code Playgroud)
第一行声明了一个char指针,并将其"瞄准"在第一个字母中foo.由于foo是一个字符串常量,它驻留在内存中的所有其他常量.当您重新分配指针时,您将为其指定一个新值:地址bar.但原始字符串foo保持不变.您已移动指针,但未更改数据.
但是,在声明数组时,根本不会声明指针.你需要保留一定数量的内存并给它一个名字.所以行
char c[5] = "data";
Run Code Online (Sandbox Code Playgroud)
以字符串常量开头data,然后分配5个新字节,调用它们c,并将字符串复制到它们中.您可以像声明指向它们的指针一样访问数组的元素; 数组和指针(以大多数用途)可以这种方式互换.
但由于数组不是指针,因此无法重新分配它们.
你不能c在其他地方制造"点",因为它不是指针; 它是记忆区域的名称.
您可以更改字符串的值,一次更改一个字符,或者通过调用以下函数strcpy():
c[3] = 'e'; // Now c = "date", or 'd', 'a', 't', 'e', '\0'
strcpy(c, "hi"); // Now c = 'h', 'i', '\0', 'e', '\0'
strcpy(c, "too long!") // Error: overflows into memory we don't own.
Run Code Online (Sandbox Code Playgroud)
效率提示
另请注意,初始化数组通常会复制数据:将原始字符串从常量区域复制到数据区域,程序可以在其中更改它.当然,这意味着你使用的内存是你预期的两倍.您可以通过声明指针来避免复制并通常节省内存.这使得字符串保持在常量区域,并且只为字符分配足够的内存,而不管字符串的长度如何.