前言
本文记录本人在mooc学习c语言字符串遇到的一些重要的知识点
一、字符
1.混合输入
观察下列代码有何不同?
scanf("%d %c",&i,&c);
scanf("%d%c",&i,&c);
第一行代码无论怎么输入都不会出现问题
第二行代码在输入时如果加了空格会出现问题
以下为实例
实例代码
#include <stdio.h>
int main() {
int i;
char c;
// scanf("%d %c", &i, &c);
scanf("%d%c", &i, &c);
printf("i=%d,c=%d,c='%c'", i, c, c);
return 0;
}
控制台输入12 c
结果会打印:i=12,c=32,c=’ ’
注意:空格(Space)的ASCII码值是:32
所以这里实际是读取了空格而不是字符c
2.逃逸字符
字符 | 意义 | 字符 | 意义 |
---|---|---|---|
\b | 回退一格 | \" | 双引号 |
\t | 到下一个表格位 | \’ | 单引号 |
\n | 换行 | \\ | 反斜杠本身 |
\r | 回车 | \0 | 0 |
注意:
\r表示将当前的光标移动到行首,但不会移动到下一行;\n表示将光标移动到下一行,但不会移动到行首。单独一个\r或\n都不是一般意义上的回车,\r\n放在一起才是。通常在写程序的时候只要一个\n就可以了,这是因为编译器会自动将\n替换成\r\n。
要在双引号里面输入双引号可参考以下代码
实例代码
#include <stdio.h>
int main() {
//打印双引号
printf("\"");
printf("请输入身高的英尺和英寸,如输入\"5 7\"表示5英寸7英尺");
printf("\"");
printf("\n");
//单引号
printf("\'");
printf("\n");
//回退
printf("123\bA\n456\n");
//反斜杠
printf("\\");
printf("\n");
//表格位
printf("123\t456");
printf("\n");
printf("12\t456");
printf("\n");
//回车
printf("abc\r\n");
return 0;
}
二、字符串
字符串是以数组的形式存在,以数组或指针的形式访问
0标志字符串结束,0=‘\0’,计算字符串长度不包含0,但是字符数组长度包含了0
char word[] = {'H', 'e', 'l', 'l', 'o', '!', 0};
char word1[] = "Hello!";
char word2[6]= "Hello!";
char *str = "Hello!";
两个相邻的字符串常量会被自动连接起来
printf("请输入身高的英尺和英寸,"
"如输入\"5 7\"表示5英寸7英尺");
printf("\n");
//或者加/
printf("请输入身高的英尺和英寸,\
如输入\"5 7\"表示5英寸7英尺");
字符串变量
字符串常量
char *s = "hello world";
以上为一个字符串常量,指针s指向了这个字符串的首地址
下面看一段代码:
#include <stdio.h>
int main() {
int i;
char *s = "hello world";
char *s2 = "hello world";
printf("i=%p\n", &i);
printf("s=%p\n", s);
printf("s2=%p\n", s2);
//s,s2地址位于只读代码段
return 0;
}
运行结果:
结果中,会发现,指针char* s和指针char* s2指向了同一个地址,而声明的本地变量i的地址在另外一片区域内。
所以:s实际上是一个指针,初始化指向一个字符串常量。
s实际的写法为const char* s,但由于历史原因编译器可支持不带const的写法。
C语言的编译器会将字符串常量存放在代码段,这个地址内数据是只读的,如果程序试图去写这个地址,那么操作系统会有一种保护机制,让程序崩溃掉:
#include <stdio.h>
int main() {
char *s = "hello world";
s[0] = 'b';
printf("s=%p\n", s);
//以上代码程序会运行失败,原因是地址位于只读代码段
return 0;
}
如果需要修改字符串,应该用数组:
#include <stdio.h>
int main() {
char s[] = "Hello, world!";
s[0] = 'b';
printf("s=%s\n", s);
return 0;
}
指针还是数组?
▲ 数组:这个字符串在这里
◆ 作为本地变量空间自动被回收
▲ 指针:这个字符串不知道在哪里
◆ 处理参数
◆ 动态分配空间
【总结】★ 如果要构造一个字符串 → 数组 ;
★ 如果要处理一个字符串 → 指针
char* 是字符串?
▲ 字符串可以表达为char* 的形式
▲ char* 不一定是字符串
◆ 本意是指向字符的指针,可能指向的是字符的数组(就像int* 一样)
◆ 只有它所指的字符数组有结尾的0,才能说它所指的是字符串