字符串
由双引号引起的一串字符就是字符串。如 "Hello,world!" 、 "abcdef" 等等。
需要注意的是,字符串的结束标志是一个 \0 的转义字符。而计算字符串长度时 \0 是结束标志,不算作字符串内容。
char arr[] = "Hello,world!"; //你看到的是这样
char arr[] = "Hello,world!\0"; //实际上长这样
也就是说字符串在结尾处都隐藏了一个 \0 的字符。这两条代码中的 [ ] 是创建数组的意思,[10] 这就是数组中有十个元素的意思。
#include <stdio.h>
int main()
{
char arr1[] = "Hello";
char arr2[] = {'H','e','l','l','o'};
printf("%s\n",arr1); //Hello
printf("%s\n",arr2); //Hello +(乱码)
return 0;
}
用上面这段代码打印两个看似相同的东西,但最终结果却是不同,arr2 在 Hello 后面多出了一段乱码。这也变相验证了字符串后面是隐藏了 \0 的结束转义字符,而 arr1 不是字符串所以后面没有隐藏的 \0 结束标志,所以当打印完 Hello 后没有停止,而是继续打印这个内存后面的未知内容,出现了这段乱码。
#include <stdio.h>
int main()
{
char arr1[] = "Hello";
char arr2[] = {'H','e','l','l','o','\0'};
printf("%s\n",arr1); //Hello
printf("%s\n",arr2); //Hello
return 0;
}
当在 arr2 中手动添加了 \0 后得到的结果就是与 arr1 一样的 Hello 了。
这是其中一种验证 \0 是结束标志的方法,下面是另外一种。
#include <stdio.h>
#include <string.h>
int main()
{
int length = strlen("Hello"); //5
printf("%d\n",length);
return 0;
}
这里用到了一种新的函数 strlen (string length),求字符串的长度,使用格式如上,使用前需要提前引用 string.h 的头文件,与使用 printf 函数类似。
得出的结果是 5 ,这也就是上面说的 \0 不算作字符串内容。
#include <stdio.h>
#include <string.h>
int main()
{
char arr1[] = "Hello";
char arr2[] = {'H','e','l','l','o'};
printf("%d\n",strlen(arr1)); //5
printf("%d\n",strlen(arr2)); //随机值
return 0;
}
使用上述代码得出的结果 arr1 是5;arr2 是一个随机值。
arr1 得到5很好理解。arr2 中由于没有 \0 作为结束标志导致 strlen 计算长度时没有到'o'就结束,而是继续向后计算内存中的未知内容,直到碰到 \0 结束计算,这就是得出随机值的原因。
#include <stdio.h>
#include <string.h>
int main()
{
char arr1[] = "Hello";
char arr2[] = {'H','e','l','l','o','\0'};
printf("%d\n",strlen(arr1)); //5
printf("%d\n",strlen(arr2)); //5
return 0;
}
当主动放入'\0'后可以发现结果均为5。
=========================================================================
转义字符
转义字符在之前两天已有涉及,如 \n、\0等。
这也会出现一些问题,比如想要打印12\n34,得出的结果却是:
12
34
再比如想要打印个单引号,前面两个单引号会被识别为一对。
#include <stdio.h>
int main()
{
printf("%c\n",''');
return 0;
}
这时就需要使用转义符号避免这种情况的发生。
#include <stdio.h>
int main()
{
printf("%c\n",'\'');
return 0;
}
#include <stdio.h>
int main()
{
printf("12\\n34");
return 0;
}
常见转义字符:
\? 在书写多个连续问号时使用,防止他们被解析成三字母词(大多编译器已不支持三字母词)
\' 用于表示字符常量'
\" 用于表示一个字符串内部的双引号
\\ 用于表示一个反斜杠,防止他被解释为一个转译序列符
\a 警告字符,蜂鸣
\n 换行
\r 回车
\t 水平制表符
\ddd ddd表示1~3个八进制数字
\xdd dd表示两个十六进制数字
\b 退格符
\f 进纸符
\v 垂直制表符
这里着重来看 \ddd 和 \xdd 。
#include <stdio.h>
int main()
{
printf("%c\n",'\130'); //X
return 0;
}
其中 \130 是八进制,转换成十进制是多少呢?
以十进制130为例,单位分别对应的是
1 3 0
10^2 10^1 10^0
得到十进制为 1*10^2+3*10^1+0*10^0 = 130
八进制同理,八进制130的单位分别对应的是
1 3 0
8^2 8^1 8^0
得到十进制为 1*8^2+3*8^1+0*8^0 = 88
而 X 的 ASCII 码值是88,所以 printf("%c\n",'\130'); 的逻辑就是:%c 打印字符 '\130' ,八进制\130 转换成十进制88,根据ASCII码值88转换成对应字符 X 。
ASCII码值表
\xdd 同理
#include <stdio.h>
int main()
{
printf("%c\n",'\x30'); //0
return 0;
}
十六进制30转换为十进制为48,对应ASCII码值得到 0 。
这里再回顾一下%d、%s、%c
//printf("%d/n",100); 打印整型
//printf("%s/n",'abc'); 打印字符串
//printf("%c/n",'a'); 打印字符
---------------------------------------------------------------------------------------------------------------------------------
笔试题
求输出结果。
#include <stdio.h>
#include <string.h>
int main()
{
printf("%d\n",strlen("c:\test\328\test.c"));
return 0;
}
解析:
c:\test\328\test.c
其中 \t 、\32 、\t 为转义字符,是一个整体,共3个。
\32 而不是 \328 原因是 \ddd 转义字符是八进制,不存在 8 。
所以输出结果是14。
=========================================================================
注释
1.代码中有不需要的代码可以直接删除也可以注释掉。
2.代码中有些代码比较难懂,可以加一下注释文字。
//这是C++的注释风格,更加常见,更加好用。
/*
C语言的注释风格,有缺陷,不支持嵌套注释。
*/