C语言篇 -(1)初识C语言 - (5)字符串-转义字符-注释
简介:
大家好,我是小奔,每天一笔记,从最基础开始写,展现我自己学习过程,如果感觉不错,就点一下关注啦
纠正:
字符串
这一篇博客我们来了解一下字符串,看下面这个我们熟知的也是最先学习的代码
"Hello world!"
这一堆的字母就是字符串字面值,简称字符串,每一个字母都是一个字符,字符串需要用" "双引号来引起,字符需要用’ '单引号来引起,就像下面
"Hello world!" //字符串
'a' //字符
'!' //字符
字符串也算常量,上面三条都算字面常量,之前的讲常量的时候就举过这种例子
那么字符串有什么用呢?
假设我们要把下面的字符串存起来,那么我们需要怎么存呢?
"abcdef"
我们可以把它放在字符串数组里,有两种形式如下:
#include<stdio.h>
int main()
{
char arr1[10]="abcdef"; //形式一
char arr2[10]={'a','b','c','d','e','f'}; //形式二
//我们打印一下这些字符串
printf("%s\n",arr1);
printf("%s\n",arr2);
return 0;
}
运行的结果:
abcdef
abcdef
把"abcdef"都存在arr[ ]这个数组里面,[ ]里面数是多少,就能存多少字符
arr[10]可以存10个字符 ,但一定要不小于你要存的字符
你也可以不写[ ]里面的数字,它会自己根据你要存的字符串来调整,就像这样
#include<stdio.h>
int main()
{
char arr[]="abcdef"; //char-字符类型,没有字符串类型哦
return 0;
}
那这两种形式有什么区别呢?
我们不写arr[ ]里面的数字,我们来看一下
#include<stdio.h>
int main()
{
char arr1[]="abcdef";
char arr2[]={'a','b','c','d','e','f'};
//我们打印一下这些字符串
printf("%s\n",arr1);
printf("%s\n",arr2);
return 0;
}
运行的结果:
abcdef
abcdef烫烫烫烫烫abcdef
哎,发现没有,它们不一样了,那为什么会出现这种情况呢?
先想一个问题,它是根据什么来停止打印的?
(啊,你会问:它们后面啥都没有,我怎么会知道它们根据什么来停下来的)
那里确实看不见有什么标志,但是那个标志就是看不见的,字符串的结束标志是\0,它是一个我们马上就会学到的转义字符
char arr1[]="abcdef";
这个形式一,字符串后面就默认带了一个\0
char arr2[]={'a','b','c','d','e','f'};
这个形式二,后面没有\0
懂了吧,printf去打印的时候要识别到\0才会结束
第一个形式最后一个字符结束就识别到了\0,然后结束
第二个形式识别到最后的f,一直都没有识别到\0,就一直打印下去,最后就出现刚才的结果
那么如果我们给第二个形式加一个\0作为结束标志怎么样,不要光想,我们来做一下试试
#include<stdio.h>
int main()
{
char arr1[]="abcdef\0"; //我们也试一下给它也加一个\0
char arr2[]={'a','b','c','d','e','f','\0'};
//我们打印一下这些字符串
printf("%s\n",arr1); //%s是打印字符串的
printf("%s\n",arr2); //%s是打印字符串的
return 0;
}
运行的结果:
abcdef
abcdef
结果运行正常了
那么\0算不算里面的字符串长度的一部分呢?
又来介绍一个好东西,strlen,它可以计算一个字符串长度的函数,但是使用它还是跟以前一样,需要给另一个头文件string.h打一下招呼才能使用它,我们来实操一下:
#include<string.h>
#include<string.h>
int main()
{
char a[] = "abc";
char b[] = "abc\0";
printf("%d", strlen(a));
printf("%d", strlen(b));
return 0;
}
运行结果:
3
3
"abc"
这个字符串的长度为3,所以我们可以知道看不见的\0并不算在长度里面的,就算在后面加上\0也是一样
大家可以试一试计算一下第二种形式不加\0情况下的字符串长度,保持好奇心,去自己尝试一下。
就这样,我们把"abcdef"这个数组储存起来了,那我们要使用里面的字符怎么办?我们还需要再了解一个知识:
调用arr里面字符,用arr[2]就可以调用c,用arr[0]就可以调用a,它们的对应关系也就是:
a b c d e f
0 1 2 3 4 5
我们来实验一下
#include<stdio.h>
int main()
{
char arr[]="abcdef";
printf("%c",arr[2]);
return 0;
}
运行结果:
a
#include<stdio.h>
int main()
{
char arr[]="abcdef";
printf("%c",arr[0]);
return 0;
}
运行结果:
a
转义字符
今天我们来了解一下转义字符,转义字符顾名思义就是转变意思。
现在了解一下这些字符:
转义字符 释义
\? 在书写连续多个问号时使用,防止他们被解析成三字母词
\' 用于表示字符常量'
\“ 用于表示一个字符串内部的双引号
\\ 用于表示一个反斜杠,防止它被解释为一个转义序列符。
\a 警告字符,蜂鸣
\b 退格符
\f 进纸符
\n 换行
\r 回车
\t 水平制表符
\v 垂直制表符
\ddd ddd表示1~3个八进制的数字。 如: \130 X
\xdd dd表示2个十六进制数字。 如: \x30 0
为什么要使用这些转义字符呢?
我们来说一下三字母词(过去有,现在使用的编译器不使用它了,所以就演示不了了),如果我们要打印一些字符,比如??)
,在三字母词中它对应的符号是]
??) --> ]
??( --> [
表示的是你本来想要打印的是??)
这三个符号,但是在编译器看来,它们是]
,所以它会给你打印出],而不是??)
那么你就想要打印出 ??)
怎么办呢?
我们只需要把??)
前加一个 \
即
\?\?)
//转义字符 \?
它可以让?
变成不是三字母词中的?
,让它老老实实的就是一个?
,所以编译器就不会打印出 ]
三字母词实在是太古老了,但是这个语法不能消失,所以我们一直都在使用转义字符
这里总结一下我们打印所用到的格式
//%d - 打印整型
//%c - 打印字符
//%s - 打印字符串
//%f - 打印float类型的数据
//%lf - 打印double类型的数据
//%zu - 打印sizeof的返回值
如果我们要打印一个字符,如下:
#include<stdio.h>
int main()
{
printf("%c",'''); //我们来打印'
return 0;
}
运行结果:
出现了错误
那么出错的原因是什么?
我们来看这 '''
,printf识别的时候,识别第一个 '
,然后再识别一个 '
,哎,到这里就结束了,就像识别这个字符一样'w'
,只要识别到一对儿'
,打印就会结束,但是后面还有第三个 '
是多余的,就出错了
那么,我们使用转义字符 \'
,让'
不再是一对儿'w'
里面的'
,就像上面的??)
一样
验证一下:
#include<stdio.h>
int main()
{
printf("%c",'\''); //我们来打印'
return 0;
}
//转义字符 \'
运行的结果:
’
再来继续了解转义字符
我们打印字符串有两个形式:
#include<stdio.h>
int main()
{
printf("%s\n","abcdef"); //形式一
printf("abcdef"); //形式二
return 0;
}
第二种形式不能直接像下面这样打印:
printf(2123456)//错误的
如果我们在abcdef
中间加一个\0
,但因为它代表的是换行,所以我们需要让它失效,让\0
就是\0
,没有其他含义,只需要这样就可以了:
#include<stdio.h>
int main()
{
printf("%s\n","abc\\0def"); //形式一
printf("abc\\0def"); //形式二
return 0;
}
//转义字符 \\
上面那个表里的转义字符都是这样子来使用的
来练习一个题
#include <stdio.h>
#include <string.h>
int main()
{
printf("%d\n", strlen("c:\test\121"))
return 0;
}
它的输出结果是什么?
答案解析:
strlen:获取字符串的有效长度,不包括’\0’
“c:\test\121”: 在该字符串中,\t是转移字符,水平制表,跳到下一个tab的位置;而\121表示一个字符,是讲121看做8进制数组,转换为10进制后的81,作业为ASCII码值的字符,即:字符’Q’ ,故上述字符串实际为:“c: esty”,只有7个有效字符
如果我们真的要打印c:\test\121
,需要变成c:\\test\\121
,这样就可以把c:\test\121
给打印出来
关于转义字符,我们只需要记住特殊的就行,没有必要全部记忆,我们以后是会用到一些的
注释
在之前小奔写代码的时候,你会经常看到//
//
这个是注释,注解解释的意思,它可以让一段代码无效化,常用作解释一段代码的作用
就像这样:
int main()
{
//创建指针变量p,并赋值为NULL
int* p = NULL;
return 0;
}
//
这个是c++的注释方式,还有一种注释的方式/* */
如下:
int main()
{
//int a = 10;
int a = 10;
int b = 20;
//创建指针变量p,并赋值为NULL
int* p = NULL;
return 0;
}
/*
int main()
{
//int a = 10;
int a = 10;
int b = 20;
//创建指针变量p,并赋值为NULL
int* p = NULL;
return 0;
}
*/
可以看到下面那个已经被注释掉了,这个注释方式是c语言的注释方式
那么你认为哪一种会比较好呢?
我的老师说都好,各有千秋,不过我比较喜欢//这一种
因为/* */
这种注释不能嵌套
就像这样:
/*
int main()
{
//int a = 10;
/*int a = 10;
int b = 20;*/
//创建指针变量p,并赋值为NULL
int* p = NULL;
return 0;
}
*/
你可以观察到,我现在最外面加了/* */
,又想在里面的
int a = 10;
int b = 20;
加一下注释/* */
,但是没有实现,它不能嵌套(套娃)
梳理一下注释的作用:
- 注释可以梳理梳理
- 对复杂的代码进行解释
- 写代码的时候写注释,是帮助自己,帮助别人的
老师建议:
写代码的时候记得养成写注释的习惯,这对以后面试很有好处,也在工作中有便利,方便别人去理解,也可以给面试官一个好印象