1 C语言中的字符串
1.1 字符串的概念
C语言中字符串的概念如下:
- 字符串是有序字符的集合。
- 字符串是程序中的基本元素之一。
- C语言中没有字符串的概念:
- C语言中通过特殊的字符数组模拟字符串。
- C语言中的字符串是以’\0’结尾的字符数组。
1.2 字符数组与字符串
在C语言中,双引号引用的单个或多个字符是一种特殊的字面量:
- 存储于程序的全局只读存储区。
- 本质为字符数组,编译器自动在结尾加上’\0’字符。

(除了第一个不是,其余都是。)
对于字符串,我们还需要知道:
- 字符串字面量的本质是一个数组。
- 字符串字面量可以看作指针常量。
- 字符串字面量中的字符不可改变。
- 字符串字面量至少包含一个字符。
"Hello World"是一个无名的字符数组。

(上面的结果分别为:‘a’,‘2’, ‘\0’。)
1.3 字符串的长度
关于字符串的长度:
- 字符串的长度就是字符串所包含字符的个数。
- 字符串长度指的是第一个’\0’字符前出现的字符个数。
- 通过’\0’结束符来确定字符串的长度。
- 函数strlen用于返回字符串的长度。
- 字符串相关函数都依赖于结束符’\0’。
2 字符串典型问题分析
2.1 snprintf的问题
对于下面的程序会输出什么?

vs中输出结果如下:

分析:
snprintf函数本身是可变参数函数,原型如下:int snprintf(char* buffer, int buf_size, const char* format, ...)。当函数只有3个函数时,如果第三个参数没有包含格式化信息,函数调用没有问题(编译器会给出警告);相反,如果第三个参数包含了格式化信息,但缺少后续对应参数,则程序行为不确定。格式化信息必须与变参个数相匹配。
再看一段代码:
#include <stdio.h>
#include <string.h>
int main()
{
#define STR "Hello, \0D.T.Software\0"
char* src = STR;
char buf[255] = {0};
snprintf(buf, sizeof(buf), src);
printf("strlen(STR) = %d\n", strlen(STR));
printf("sizeof(STR) = %d\n", sizeof(STR));
printf("strlen(src) = %d\n", strlen(src));
printf("sizeof(src) = %d\n", sizeof(src));
printf("strlen(buf) = %d\n", strlen(buf));
printf("sizeof(buf) = %d\n", sizeof(buf));
printf("src = %s\n", src);
printf("buf = %s\n", buf);
return 0;
}
/* 输出结果
strlen(STR) = 7
sizeof(STR) = 22
strlen(src) = 7
sizeof(src) = 4
strlen(buf) = 7
sizeof(buf) = 255
src = Hello,
buf = Hello,
*/
分析:
- 字符串相关的函数均以第一个出现的’\0’作为结束符。
- 编译器总是会在字符串字面量的末尾添加’\0’。
- 字符串字面量的本质为数组。
- 字符串、字符数组、字符指针三者不同。
2.2 字符串的比较问题
直接看如下代码:
#include <stdio.h>
#include <string.h>
int main()
{
#define S1 "D.T.Software"
#define S2 "D.T.Software"
if( S1 == S2 )
{
printf("Equal\n");
}
else
{
printf("Non Equal\n");
}
if( strcmp(S1, S2) == 0 )
{
printf("Equal\n");
}
else
{
printf("Non Equal\n");
}
return 0;
}
/*
vs、gcc中输出:Equal、Equal。
bcc中输出:Non Equal、Equal。
*/
分析:
- 字符串之间的相等比较需要用strcmp完成。
- 不可直接使用==进行字符串直接的比较。
- 完全相同的字符穿字面量的 == 比较结果为false,但是一些现代编译器能够将相同的字符串字面量映射到同一个无名字符数组,因此==比较结果为true。我们应该不编写依赖特殊编译器的代码!
参考资料:
6359

被折叠的 条评论
为什么被折叠?



