博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C语言进阶:第31课:字符串典型问题分析
阅读量:3736 次
发布时间:2019-05-22

本文共 2698 字,大约阅读时间需要 8 分钟。

下面的程序输出什么,为什么?

char buf[10] = {0};	char src[] = "hello %s";		snprintf(buf, sizeof(buf), src);		printf("buf = %s\n", buf);

编译运行:

~/will$ gcc test.ctest.c: In function ‘main’:test.c:9: warning: format not a string literal and no format argumentstest.c:9: warning: format not a string literal and no format argumentsdelphi@delphi-vm:~/will$ ./a.outbuf = hello ??

snprintf函数本身是可变参数函数,原型如下:

int snprintf(char* buffer, int buf_size, const char* format,...)

当函数只有三个参数时,如果第三个参数没有包含格式化信息,函数调用没有问题;相反,如果第三个参数包含了格式化信息,但缺少后续对应参数,则程序行为不确定。(必须存在第四个参数——字符串)

修改程序如下:

int main(){	char buf[10] = {0};	char src[] = "hello %s";		snprintf(buf, sizeof(buf), src, "123");		printf("buf = %s\n", buf);		return 0;	}

编译运行:

~/will$ ./a.outbuf = hello 123
下面的程序输出什么,为什么?
#include 
#include
int main(){ #define STR "hello, \0willwilling\0"    //hello,后有个空格 char* src = STR; char buf[255] = {0}; snprintf(buf, sizeof(buf), src);    //字符串操作函数 printf("strlen(STR) = %d\n", strlen(STR));    //7 printf("sizeof(STR) = %d\n", sizeof(STR));    //21 printf("strlen(src) = %d\n", strlen(src));    //7 printf("sizeof(src) = %d\n", sizeof(src));    //4 printf("strlen(buf) = %d\n", strlen(buf));    //7      printf("sizeof(buf) = %d\n", sizeof(buf));    //255         printf("src = %s\n", src);  //hello,    printf("buf = %s\n", buf);   //hello,    printf("STR = %s\n", STR);   //hello, char SS[255] = "hello, \0willwilling\0"; printf("SS = %s\n", SS);    //hello, return 0; }
字符串相关的函数均以第一个出现的
'\0'作为结束符;
编译器总是会在字符串字面量的末尾添加'\0';

字符串字面量的本质为数组。

字符串、字符数组、字符指针有联系,但是是不同的。

下面的程序输出什么为什么?

int main(){    #define S1 "willwilling"    #define S2 "willwilling"    if( S1 == S2 )  //GCC的优化    {	    printf("Equal\n");    }    else    {	    printf("No Equal\n");    }        if( strcmp(S1, S2) == 0)    {	    printf("Equal\n");    }    else    {	    printf("No Equal\n");    }		return 0;	}

编译运行:

delphi@delphi-vm:~/will$ ./a.outEqualEqual

S1 和 S2 的比较,在编译的时候,对于已经定义的字符串字面量,(已经存在于只读存储区)编译器会进行优化,S1和S2是同一个。

printf("S1 = %p\n", S1);    printf("S2 = %p\n", S1);

编译运行结果:

~/will$ ./a.outEqualEqualS1 = 0x804851fS2 = 0x804851f
字符串之间的相等比较需要用strcmp完成;
不可直接使用"=="进行字符串比较;

完全相同的字符串字面量的 == 比较结果为false(一些旧的编译器)

一些现在的编译器能够将相同的字符串字面量映射到一个无名字符数组,因此 "=="比较结果为true。

(不能编写依赖编译器的代码)

字符串循环右移:

void right_shift_r(const char* src, char* result, unsigned int n)
函数功能: 将输入字符串src循环右移n位,result为输出结果;
要求:
以效率最高的方式实现
示例:
"abcde"  --2--> "deabc"		"abcde"  --8--> "cdeab"
划重点:遇见问题首先分析特征:
循环右移,也就是每个元素的下标要发生变化: (i+3)%7
void right_shift_r(const char* src, char* result, unsigned int n)	{		const unsigned int LEN = strlen(src);		int i;				for(i=0; i

编译运行:

~/will$ ./a.out	deabc	cdeab
良好的分析问题的习惯,抓住重点才能更好的解决问题。

转载地址:http://mwdin.baihongyu.com/

你可能感兴趣的文章
#剑指offer Day4 一类 “ 双指针 ”问题
查看>>
#剑指offer Day5 # 分享两个题的其他解法
查看>>
缓存淘汰算法的实现与应用介绍(LRU,LFU)
查看>>
JZ15. 反转链表
查看>>
1. 两数之和
查看>>
2. 两数相加
查看>>
JZ1.二维数组的查找
查看>>
String 类
查看>>
什么是接口
查看>>
Java高级篇之进程
查看>>
类加载机制
查看>>
了解jdk1.8版本一些新的特性
查看>>
Java高级篇之网络通讯
查看>>
浅谈篇之线程池
查看>>
Lambda 表达式
查看>>
字符串函数MySQL
查看>>
8个SQL讲解优化
查看>>
MySQL实战续(二)
查看>>
安装Elastic和kibana
查看>>
什么是搜索
查看>>