C语言中不同定义的字符串用==比较结果差异的原因咨询
关于C语言中字符串比较的三个场景解析
一、三个场景的结果原因
1. char数组的==比较为false
char name[10]="michael"; char name2[10]="michael"; if (name == name2) { printf("ok\n"); printf("OKAF\n"); }
name和name2是两个独立的char数组,编译器会为它们分配两块完全不同的内存空间。数组名在表达式中会被隐式转换为指向数组首元素的指针,所以name和name2指向的是不同的内存地址,==比较地址的结果自然是false。
2. char指针指向字符串字面量的==比较为true
char* name="michael"; char* name2="michael"; if (name == name2) { printf("ok\n"); printf("OKAF\n"); }
- 字符串字面量(比如
"michael")会被编译器存放在程序的只读数据段。为了节省内存,大多数编译器会对内容相同的字符串字面量做合并优化——让所有指向该字面量的指针都指向同一块内存地址。所以name和name2的地址完全相同,==比较结果为true。 - 注意:这是编译器的优化行为,并非C标准强制要求,不同编译器可能有不同表现,绝对不能依赖这个特性判断字符串内容是否相等。
3. 错误定义单个char变量为字符串字面量的==比较为true
char name="michael"; char name2="michael"; if (name == name2) { printf("ok\n"); printf("OKAF\n"); }
- 这是完全不符合C语言规范的错误写法:字符串字面量
"michael"本质是一个char*类型的指针,而char是仅占1字节的单个字符变量。把指针赋值给char时,编译器会将指针的地址值截断为1字节存储。 - 由于两个字符串字面量被编译器合并到同一块内存,它们的指针地址相同,截断后的1字节值自然也相同,所以
name和name2的字节值相等,==比较结果为true。但这种写法会触发未定义行为,绝对不能使用。
二、不用strcmp实现字符串比较的原理
strcmp的核心逻辑是逐字符对比ASCII值,直到遇到不同字符或字符串末尾('\0')。自己实现的话,原理完全一致:
- 同时遍历两个字符串的每个字符;
- 对比当前位置的字符:
- 若字符不同,返回两者的ASCII差值(正数表示前者更大,负数表示后者更大);
- 若字符相同,继续遍历下一个字符;
- 当其中一个字符串到达
'\0'时,检查另一个是否也到末尾:若都到了则返回0(表示相等),否则返回两者的差值('\0'的ASCII是0,所以未结束的字符串字符会和0产生非0差值)。
简单实现示例:
int my_strcmp(const char *str1, const char *str2) { while (*str1 != '\0' && *str2 != '\0') { if (*str1 != *str2) { return *str1 - *str2; } str1++; str2++; } // 处理其中一个字符串先结束的情况 return *str1 - *str2; }
内容的提问来源于stack exchange,提问作者Michael Michaels
相关产品推荐
相关产品推荐

