字符串
-
- [1. 前言](#1. 前言)
- [2. 预备知识](#2. 预备知识)
-
- [2.1 字符](#2.1 字符)
- [2.2 字符数组](#2.2 字符数组)
- [3. 什么是字符串](#3. 什么是字符串)
- 4. '\0'
-
- [4.1 '\0'是什么](#4.1 '\0'是什么)
- [4.2 '\0'的作用](#4.2 '\0'的作用)
-
- [4.2.1 打印字符串](#4.2.1 打印字符串)
- [4.2.2 求字符串长度](#4.2.2 求字符串长度)
1. 前言
大家好,我是努力学习游泳的鱼。你已经学会了如何使用变量和常量,也知道了字符的概念。但是你可能还不了解由字符构成的字符串,这篇文章将带你一探究竟。
2. 预备知识
2.1 字符
单引号引起来的一个字符,用来初始化char
类型的变量。
c
'a'; // 这是一个字符
char ch = 'w'; // 用来初始化char类型的变量
2.2 字符数组
字符数组可以存储很多字符,格式是char+空格+数组名+左方括号(+数组最多存储的字符个数,如果省略就默认取初始化的字符个数)+右方括号+初始化(大括号引起来几个字符,中间用逗号隔开)
。
c
char ch[3] = { 'a', 'b', 'c' }; // 最多存3个字符,即a,b,c
char ch[] = { 'd', 'e', 'f', 'g' }; // 方括号内省略字符个数,默认为4,因为初始化了4个字符
3. 什么是字符串
用双引号引起来的一串字符叫做字符串。
c
"abcdefg"; // 这就是一个字符串
4. '\0'
4.1 '\0'是什么
字符串可以用来初始化字符数组。
c
char arr1[] = "abc";
char arr2[] = { 'a', 'b', 'c' };
arr1
和arr2
有什么区别呢?
我们发现,arr2
就是很正常的存储了a,b,c
这3个字符,但是arr1
在后面还跟了个'\0'
。
这个'\0'
究竟是何方神圣?
字符串的结尾都隐藏了一个叫做
'\0'
的转义字符。
"abc"
这个字符串其实是4个字符:'a','b','c','\0'
,所以说,
字符串的结束标志是
'\0'
。
4.2 '\0'的作用
4.2.1 打印字符串
我们可以用printf
配合%s
打印字符串。
c
#include <stdio.h>
int main()
{
printf("%s\n", "abcdef");
return 0;
}
把上面的arr1
和arr2
打印出来会是怎样的呢?
c
#include <stdio.h>
int main()
{
char arr1[] = "abc";
char arr2[] = { 'a', 'b', 'c' };
printf("%s\n", arr1);
printf("%s\n", arr2);
return 0;
}
输出:
abc
abc烫烫烫烫烫烫烫烫烫烫bc
我们发现,字符串arr1
正常打印,但是字符数组arr2
打印出来的是个啥玩意呀?
要搞清楚这一点,就要明白arr1
和arr2
的内存布局,以及'\0'
的作用。
arr1
是用字符串"abc"
初始化的,根据前面说的,字符串的结束标志是\0
,字符串的结尾都隐藏了一个\0
,arr1数组里相当于存储了'a','b','c','\0'
四个字符。
而arr2
就不一样了,它只是单纯的用三个字符'a','b','c'
来初始化的,里面也只存放着这三个字符,后面没有'\0'
,内存中后面放了什么,我们无从知晓。
而%s
是用来打印字符串的,还是那句话,字符串的结束标志是'\0'
。
在打印arr1
时,打印了'a','b','c'
,就遇到了'\0'
这个结束标志,停止打印。
反观arr2
,打印完'a','b','c'
,没有遇到'\0'
,就继续把内存中后面的值打印出来,直到遇到'\0'
才停止。可是,我们不知道内存中后面放了啥,换句话说,内存中后面放的都是些随机值,那打印出来的也是随机值,具体表现出来就是abc
后面的烫烫烫。
如果我们手动放一个'\0'
,两个字符数组的内存布局就一样了。
c
#include <stdio.h>
int main()
{
char arr1[] = "abc";
char arr2[] = { 'a', 'b', 'c', '\0' };
printf("%s\n", arr1);
printf("%s\n", arr2);
return 0;
}
输出:
abc
abc
4.2.2 求字符串长度
我们可以用
strlen
函数求字符串长度。
strlen
是C语言提供的库函数,对应的头文件是string.h
,使用时只需要把字符串传进去就可以了。
c
#include <stdio.h>
#include <string.h>
int main()
{
char arr1[] = "abc";
char arr2[] = { 'a', 'b', 'c' };
printf("%d\n", strlen(arr1));
printf("%d\n", strlen(arr2));
return 0;
}
输出:
3
42
有了前面的知识,就很容易理解这个结果了。
arr1
里面存的是'a','b','c','\0'
,由于有'\0'
的存在,可以很清楚的求出字符串的长度是3
,也就是'\0'
前面的字符的个数。
反观arr2
,因为'a','b','c'
后面没有'\0'
,所以无法求出其长度。就这次的运行结果而言,程序在内存中一直往后找呀找呀,从'a'
开始一直找了42
个字符才在内存中遇到了'\0'
,于是算出来的结果是42
。这个结果是不可预料的,它是个随机值。
如果手动放一个'\0'
,就能够准确地求出它的长度了。
c
#include <stdio.h>
#include <string.h>
int main()
{
char arr1[] = "abc";
char arr2[] = { 'a', 'b', 'c', '\0' };
printf("%d\n", strlen(arr1));
printf("%d\n", strlen(arr2));
return 0;
}
输出:
3
3
总结:strlen求的是'\0'
前面字符的个数!