标签:bcd cee strcpy deb studio code 两种 定义 全局
c语言中的c风格字符串常有以下两种存储方式,做一个总结,希望以后不需要再出现模棱两可。
如果是char str[5]= {‘a‘,‘b‘,‘c‘,‘d‘,‘e‘},这存的就是一个字符数组,而不是一个字符串
如果是char str[6]= {‘a‘,‘b‘,‘c‘,‘d‘,‘e‘,‘\0‘} 这寸的就是一个字符串 为“abcde” (c风格的字符串),要留出一个空间存储\0表示字符串终止,等价于如下定义方式:
char str[6] = "abcde"
可以看出c风格的字符串 如果是用数组方式定义的,就要在字符串长度的基础上 + 1用来存储\0,
还有一种可以存储字符串的方式就是使用char类型的指针,比如
char *str = "abcde"
这种方式要注意,str存储的并不是字符串的内容,而是字符串的起始地址,在visual studio 的debug模式下,能看到str的值通常为 地址+ 字符串内容比如0x7fffffffeffc "abcde"表示str指向的地址,(也就是字符a的地址)也就是str指针的值是0x7fffffffeffc,以这个地址为起始地址的字符串的值是“abcde”
当使用printf()输出时,格式化时选择%s,会输出abcde,这是printf遇到结尾符号‘\0’即停止显示打印。
所以在使用char 类型的指针存储字符串的时候会发生很多意想不到的错误及问题,这就是C语言中指针让人头疼的地方。
以下说的所有字符串都是用数组存储的
scanf输入一个字符串而且是遇见空格就会停,比如输入“hello world”之后,他只会读入hello。要使用scanf("%s%s",str1,str2),才能读入hello 和world,而且hello存在str1中,world存在str2中。
scanf("%s",str);是没有取地址符号的,而且系统会自动在str最后补上\0
while(scanf("%s",str) != 1) 作用是持续读入数据 在读不到数据的时候停止循环
gets(str)就是从光标开始的地方读到换行符,和scanf的区别就是空格也能被读入,只有输入回车才会停止读入
puts(str)就是输出一个字符串和一个换行符,等价于printf("%s\n",str);
这个也可以直接读入两个字符串
strcat(s1,s2) 将字符串s2连接到s1之后
strcpy(s1,s2) 将字符串2复制到字符串1,返回字符串1的值。
strcmp(s1,s2) 比较字符串1和字符串2的大小。如果1 > 2 返回正数,如果两字符串完全相等返回0,如果1< 2返回负数
strlen(s1) 计算字符串的长度,而且不把\0算进去
strlwr(str) 将字符串全部转化为小写
strupr(str),将字符串全部转化为大写。
使用上述函数 如果是在c语言中要包含string.h头文件,如果是在c++中要包含cstring,也可以包含string.h头文件,两者区别在于cstring是对string.h头文件进行了一些修改让它更能兼容c++罢了
程序的内存分配基础,看我的另一篇博客https://www.cnblogs.com/yizhanwillsucceed/p/13578076.html
C字符串一般放在常量区,data段上.而且数组方式存储和指针方式有着很大区别。
看下面这个例子
//main.cpp
int a = 0; 全局初始化区
char *p1; 全局未初始化区
main()
{
int b; 栈
char s[] = "abc"; 数组方式存储的字符串存放在栈上,“abc”
char *p2; 栈
char *p3 = "123456"; 123456\0在常量区(Data段),p3在栈上。
static int c =0; 全局(静态)初始化为0(放在BSS段),就是
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);
分配得来得10和20字节的区域就在堆区。但是p1,p2指针是存在栈中的
strcpy(p1, "123456"); 123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。所以这个地方有时候会导致意想不到的错误。
}
一定注意:数组s储存的内容是在运行的时候赋值的,但是指针p3指向的常量区中的字符串内容是编译时就赋值的。
标签:bcd cee strcpy deb studio code 两种 定义 全局
原文地址:https://www.cnblogs.com/yizhanwillsucceed/p/13621776.html