--事物的难度远远低于对事物的恐惧!
这章我们主要来分析几个典型的字符串问题,也是面试中比较常见的题。
第一题、如下代码执行后输出什么?
#include <stdio.h> #include <string.h> int main() { #define STR "Hello, \0World\0" char* src = STR; char buf[255] = {0}; _snprintf(buf, sizeof(buf), src); //注:gcc环境下函数为snprintf(),vc环境下位_snprintf() printf("strlen(STR) = %d\n", strlen(STR)); //A printf("sizeof(STR) = %d\n", sizeof(STR)); //B printf("strlen(src) = %d\n", strlen(src)); //C printf("sizeof(src) = %d\n", sizeof(src)); //D printf("strlen(buf) = %d\n", strlen(buf)); //E printf("sizeof(buf) = %d\n", sizeof(buf)); //F printf("src = %s\n", src); //G printf("buf = %s\n", buf); //H return 0; }
下边我们来执行一下:
看看你的分析与结果相同吗?要分析以上输出,我们首先来分析下与字符串相关的内容:
-字符串相关的函数均以第一个出现的 '\0' 作为结束符,之后的内容都会被忽略!
-编译器总是会在字符串字面量的末尾添加 '\0'
-字符串字面量的本质为数组
有了以上几条基准,我们现在可以来逐一分析A~H输出语句了:
A、strlen(STR),当strlen总是以STR中的第一个'\0'之前的字符个数作为字符串长度,即得到的长度为7
B、sizeof(STR),因为字符串字面量的本质为数组,所以sizeof(STR)实际求得的就是数组在内存空间中占用的内存大小,这里别忘了,编译器会自动在STR末尾加上'\0',所以得到的输出为 14 + 1 = 15
C、strlen(src),理由同A,因为把src指向STR,而STR实际表示的字符串就为第一个'\0'之前的内容,所以src的长度也是7
D、sizeof(src),src是指针,指针在32位系统上同一占用4字节,所以输出为4
E、strlen(buf),理由可参考A跟C
F、sizeof(buf),获取的是数组在内存空间占用的空间大小,所以为255
G跟H、理由可参考A\C\E
再强调一点的就是:字符串、字符数组、字符指针三者是不相同的!
第二题、如下代码执行后输出什么?
#include <stdio.h> #include <string.h> int main() { #define S1 "Hello" #define S2 "Hello" if( S1 == S2 ) //想直接比较两个字符串 { printf("Equal\n"); } else { printf("Non Equal\n"); } if( strcmp(S1, S2) == 0 ) //调用strcmp比较两个字符串 { printf("Equal\n"); } else { printf("Non Equal\n"); } return 0; }
我们来编译执行:
从输出结果来看 S1 == S2结果为不等, strcmp(S1, S2)结果为相等
代码中的S1与S2,在内存中实际是存在两个地方的内容,也就是两个不同的字符串,仅仅是内容相同,所以S1 == S2得到的结果是不相等的,但是有些编译器(如gcc)会对这类情况进行优化,将S1与S2都映射到同一个"Hello"这个字符串,所以在gcc环境下S1 == S2是成立的;而字符串函数strcmp()的作用是比较两个字符串内容是否相等,所以输出结果是相等的。
下边来总结一下:
-字符串之间的相等比较需要用strcmp 完成
-不可直接用 == 进行字符串直接的比较
-完全相同的字符串字面量的 == 比较结果为 false
-一些现代编译器能够将相同的字符串字面量映射到同一个无名字符数组,因此在这些编译器下 == 比较会为true
第三题、字符串循环右移
核心思想如下图:
#include <stdio.h> #include <string.h> void fun(const char *src, char *result, int n) { const unsigned int LEN = strlen(src); int i=0; for(i=0; i<LEN; i++) { result[(i + n)%LEN] = src[i]; //这里注意右移数超过字符串长度时取余 } result[LEN] = '\0'; } int main() { char* src = "abcd"; int i=0; char result[255] = {0}; fun(src, result, 3); printf("%s\n", result); return 0; }
编译执行:
ok了,几个字符串常见的题就说到这。