1. 如何拼接两个字符串?
strcat() 函数,传入两个字符,将第二个字符拼接到第一个字符的后面。代码如下。
void TestStrcat(){
char* string1 = "Hello";
char* string2 = "World";
strcat(string1, string2);
printf("string1: %s\n", string1); // string1: HelloWorld
printf("string2: %s\n", string2); // string2: ld
}
需要注意的是,使用 msvc 编译器情况下,上述代码可以运行。但 string2 的字符串值会被改变,这是由于 string1 字符串地址与string2 字符串地址连续,拼接后的 string1 字符串占据了string2 字符串的内容。拼接之前:
拼接后:
若此时读取 string2,其结果为 "6c 64 00 6c 64 00 00 00",由于 00 是字符串结束标志,所以只能打印 "6c 64" 对应的内容,为 "ld"。
代码的正确写法如下。此时,string1 存储在栈区,string2 指向的内容存储在常量区。
void TestStrcat(){
char string1[20] = "Hello";
char* string2 = "World";
strcat(string1, string2);
printf("string1: %s\n", string1); // string1: HelloWorld
printf("string2: %s\n", string2); // string2: World
}
2. 字符串的复制
strcpy() 函数,会将第二个字符复制到第一个字符的起始位置。代码如下所示。可以发现,最终 string1 和 string2 的输出结果相同,原因是 string2 在复制过程中,将末尾的 '\0' 也复制到了 string1 中,导致二者的打印的结果相同。
void TestStrcpy(){
char string1[10] = "Hello C++";
char *string2 = "World";
strcpy(string1, string2);
printf("string1: %s\n", string1); // string1: World
printf("string2: %s\n", string2); // string2: World
}
需要注意的是,复制是从 string1 的起始位置进行复制,但此位置可以进行更改。如下所示,将 string1 复制的起始位置向前移动 5,获得与拼接函数相同的结果。
void TestStrcpy2(){
char string1[20] = "Hello";
char* string2 = "World";
strcpy(string1+strlen(string1), string2);
printf("string1: %s\n", string1); // string1: HelloWorld
printf("string2: %s\n", string2); // string2: World
}
3. C语言中的 char * 和 char [ ]
msvc编译器下,char * 定义的字符串,同 char[ ] 一样,可以修改任意位置的值。并且可以按照数组的样式进行修改。gcc 编译器下,此段代码无法运行。
他人博客:char * 定义的指针在栈区,但其指向的地址是字符串常量的地址,字符串常量存储在常量区,是只读区域,一旦写入程序就会崩溃。尽管 msvc 编译器不会警告,但如果使用语法严谨的 Linux 下的 C 编译器 GCC,或者在windows下使用MinGW编译器就会得到警告。相比之下,char [ ] 定义的数组存储在栈区,即数组内部的值均在栈区,为可写区域。
char * 相当于 char const *,指向的区域不可改变(指向的字符串常量不能变)。char[ ] 相当于 char *const,指针变量不能改变(即数组名不能被改变),但其指向的值可以改变(即数组内部的值可以发生变化)。
void TestChar(){
char *string1 = "hello";
*(string1) = 'a';
string1[1] = 'b';
printf("%s", string1); // abllo
}
4. 数组名 a 和 数组名取地址 &a 的关系
简单来说,a 的本质是 &a[0],即数组 a 中第一个元素的地址。&a 并不是 a 变量的地址,而是数组 a 的起始地址。数组名 a 在内存中并没有分配空间,仅仅对数组 a 的各个元素分配了存储空间,故数组名 a 不是普通的变量,&a 不意味着 a 的存储地址。
a 和 &a 的值相同,但是两者后续的含义不同。a+1 是在一个数组元素大小的基础上加 1,而 &a + 1 是在一个数组大小的基础上加 1。代码如下,可以发现,a 的值为 682621096,a+1是前进一个 int(4个字节),故结果为 682621100。而 &a + 1 是前进一个数组大小,即 20个字节,其结果为 682621116。
void Test2(){
int a[] = {1,2,3,4,5};
printf("a: %d\n", a); // 682621096
printf("a+1: %d\n", a+1); // 682621100
printf("&a+1: %d\n", &a+1); // 682621116
}
char* 和 char[ ]:https://blog.youkuaiyun.com/u012611878/article/details/78291036
数组名 a 和 数组名取地址 &a:https://blog.youkuaiyun.com/loongkingwhat/article/details/78910921