概述
????接下来就让小奔来带着大家简单的了解一下C语言,不过看起来挺多的,哈哈哈,写了大概八十个小时吧,不过小奔是在20几天前才开始学的哦,这里只是简单带着大家对C语言有一个轮廓的认识,小奔会持续更新的
入门第一个语言——C语言
- ????0. 看前须知
- ????1. 学C语言前期的准备
- ????1.1 建议
- ????1.2 安装相关的软件
- ????2. 什么是C语言
- ????3. 第一个c语言程序
- ????4.数据类型
- ✨5. 变量和常量
- ✨5.1变量
- ✨5.1.1定义变量
- ✨5.1.2变量的分类
- ✨5.1.3变量的使用
- ✨5.1.4 变量的作用域和生命周期
- ✨5.1.4.1 作用域
- ✨5.1.4.2 生命周期
- ✨5.1.5 变量的命名:
- ✨5.2常量
- ✨5.2.1 常量的定义
- ✨5.2.2 常量的分类
- ✨5.2.2.1 字面常量
- ✨5.2.2.2 const修饰的常变量
- ✨5.2.2.3 #define 定义的标识符常量
- ✨5.2.2.4 枚举常量
- ????6. 字符串
- ????7. 转义字符
- ????8.注释
- ????9. 顺序语句
- ????10. 选择语句
- ????11. 循环语句
- ????12. 函数
- ????13. 数组
- ????13.1数组的定义
- ????13.2数组的小标
- ????13.3数组的使用
- ????14. sizeof和strlen头文件的的区别
- ????15. 操作符
- ????16. 关键字
- ????17. 关键字typedef
- ????18. 关键字static
- ????18.1 static修饰的局部变量
- ????18.2 简单介绍一下void
- ????18.3 static修饰的全局变量
- ????18.4 static修饰的函数
- ????19. 关键字register
- ????20. #define定义的宏
- ????21. 指针
- ????21.1 内存
- ????21.2 指针变量的大小
- ⛺22. 结构体
- ⛺22.1 结构体的初始化
- ⛲下载链接
目录
????0. 看前须知
????对于我们这些才步入编程界的小生来说,有一个方向尤为重要,但是无论选择哪个方向,有一门计算机语言是我们都要去学习的,这门计算机语言就是C语言
????为什么说C语言是我们都要学习的呢?
????我问过鹏哥,如果你想入手编程的话,而且也是一门比较经典的语言,以这门语言作为编程入门的语言是比较合适的
????C语言在编程领域的用途的话,一个C++开发工程师他必然要懂C语言对吧,因为C语言和C++本质上是不分家的,在学完C之后,再延伸往后学习C++,这个时候就可以做C++开发工程师对吧,如果你学了C之后,要走Linux方向,那这个时候呢可以做Linux C的一个开发,甚至可以做底层的驱动开发,都是没有任何问题的,或者做一些嵌入式开发,驱动开发,包括系统开发都是需要C ,Linux这一套的
????接下来,学完C语言之后,对于其他编程语言的学习也更加容易一些,因为C语言简单对吧,容易上手,而且它是一门偏底层的计算机语言,它让你更加了解内存底层的一些原理之类的,学完之后,你再学习其他计算机语言都会变得非常容易,得心应手
????1. 学C语言前期的准备
????1.1 建议
跳转到目录末尾
1.喜欢分享
要习惯去分享,可以向我一样写博客,就是要去把自己的观点分享出来,不能闭门造车,善于分享的人对以后的工作有非常的优势。(找工作的时候,哎,把自己的博客链接一贴,面试官看了就能知道你是一个喜欢分享的人,会有很好的印象。)
2.要去实践,去刷题
学习编程必须去实践,去刷题,我推荐一些网站,可能还有不知道的其他很不错的刷题网站,我了解后会补充在这里。
链接:
牛客网
3.建立一个自己的仓库
学编程要建立一个自己的仓库,我听过程序猿敲过的代码,它能运行就行,你稍微一改,可能就改了一个数,就运行不了,但是你可能就会忘记改的哪里,或者电脑死机,你写的代码就在里面,取不出来,这时候如果有一个仓库储存着这些代码,需要的时候重新把这个代码从仓库里拿出来,就不会怕上面这种情况。
我使用的是gitee,这个跟博客有一个相同的作用,就是面试的好工具,大公司都喜欢这个,里面还有一个贡献度,
你每上传一次代码,上面都会有记录,你这天上传的次数越多,绿点就会越深,而且也可以点击这个绿点来查看这一天所上传的代码,在面试的时候非常有帮助。所需要的软件都存在百度网盘的,就在最下面链接中。
????1.2 安装相关的软件
跳转到目录末尾
1.如何安装编译器呢?
快看鹏哥的视频
(吹爆他,太强了)
2.如何使用
gitee
呢?
还是看鹏哥的视频
(鹏哥是真的强)
????2. 什么是C语言
跳转到目录末尾
c语言是一门计算机语言(比如c++/java/python…),常用于底层开发,跟人类交流的语言类似,它是人与计算机交流的语言。
计算机语言的发展:低级–>高级
发展到C语言时,已经是高级语言了
语言形式 例:
二进制的指令 1001010
汇编语言 ADD
C语言的国际标准:ANSI C(常用的是C89,C90还包括C99,C11…)
编译C语言的编译器主要有
MSVC
(作者目前使用),GCC,Clang,WIN-TC,Turbo C等
C/C++是编译型的语言,要把源代码(
test.c
), 编译为程序(test.exe
), 需要4个过程(下面四个过程)
初步了解编译器运行过程:
我们都知道计算机使用的是
二进制
语言,我们生活在十进制的世界,
二进制就例如10010101
,逢二进一;
八进制就例如157643235
,逢八进一;
十进制就例如95124921
,逢十进一;
十六进制就例如A5B46
,逢十六进一。(A指10,B指11,依次类推)
二进制 八进制 十进制 十六进制
1 1 1 1
10 2 2 2
111 7 7 7
1000 10 8 8
1001 11 9 9
1010 12 10 A
1101 15 15 E
1110 16 16 10
1011001011 1313 715 2CB
那么计算机为什么要使用
二进制
语言而不去使用八进制
,十进制
,甚至十六进制
的语言呢,这是物理方面的原因,只有二进制
比较好实现,
灯亮则是1
灯灭则是0
从物理方面好实现,其他的进制都不太好实现,这里就先简单了解一下
????3. 第一个c语言程序
跳转到目录末尾
我们在敲出第一个C语言程序前先思考一下,为什么要写代码?
当然是为了解决生活中的问题(比如购物、点餐、看电影等)
????1.打开VS
跳转到目录末尾
????2.创建新建项目
跳转到目录末尾
????3.选择空项目
跳转到目录末尾
????4.输入项目名称并创建
跳转到目录末尾
我这里推荐把项目名称改为当天的日期,存放在一个统一的位置,方便自己查找,也方便自己把代码上传仓库
????5.创建源文件
跳转到目录末尾
在解决方案资源管理器那里的源文件右击,就可以弹出来那些选项(如果一不小心把解决方案资源管理器关了,不要关掉整个软件,你可以点最上面的视图,再点击解决方案资源管理器就可以了)
注意:记得把名称的后缀.cpp
改为.c
C的语法和C++的语法是有所差别的
.cpp后缀 编译器会按照C++的语法来编译代码
.c后缀 编译器会按照C的语法来编译代码
我们目前使用的是C语言,在后面的C++学习篇中再来使用
.cpp
后缀
????6.写代码
跳转到目录末尾
//
这个是写注释的,即把这一横行的代码无效化
vs2019环境如何运行代码:
运行按键ctrl+f5
或fn+ctrl+f5
#include<stdio.h>
//c语言代码中一定要有main函数
//也就是主函数
//printf是一个库函数,是专门用于打印数据的
//标准的main(主)函数写法
int main()
{
printf("Hello world!");
return 0;
}
//古老的写法-不推荐
//void main()
//{
//
//}
运行的结果:
打印了一个
Hello world!
????解释:
跳转到目录末尾
1.
#include<stdio.h>
是在程序编译之前要处理的内容,称为编译预处理命令(还记得上一个博客里面编译器运行的四个过程吗,第一个过程就是预处理)
std—指标准(standard)
i—指输入(input)
o—指输出(output)
2.
int main() { return 0; }
是C语言main函数(也叫主函数)的一种声明方式(我目前写的简单的代码都要套用这个模板,还不清楚的看之后发的博客所示代码就能明白),这里的int
是数据类型(下一个博客会讲)里面的整型(比如6,48,99
等的整数),int
对应后面的是return 0
;
return 0
即返回值为0
,因为int
是整型,所以要求返回值也符合int
,这个0
也可以是其他数,但我们俗称规定的就是0
,就不要搞特殊写4
,5
什么其他的数字了。
3.
printf(" ");
库函数,专门用来打印数据的,c语言提供这个库函数,是不是你的?当然不是,它是别人给你的,所以你要用的时候需要打个招呼,这个头文件#include<stdio.h>
就是用来打招呼的,说我要用这个printf
这个库函数
????4.数据类型
跳转到目录末尾
之前说过写代码是为了解决生活中的问题,比如购物。
假设我们要买一本书,它的价格是
10.5
,是个小数,也可以是一个整数10
,它的书名是钢铁是怎样炼成的,是一组字符串,就像svli@gikvw
这些,里面每个称为字符。
我们要去用c语言来去存储这些信息呢,在c语言里面为了能够描述这些类型。
就把小数抽象出来一个数据类型,叫浮点型
把整数抽象出来一个数据类型,叫整型(就是上面的
int
)
把字符抽象出来一个数据类型,就叫字符
10.5 - 小数 - 浮点型
10 - 整数 - 整型
A - 字符 - 字符
那么c语言里面抽象出来哪些数据类型呢?
char //字符数据类型
short //短整型
int //整型
long //长整型
long long //更长的整型
float //单精度浮点数
double //双精度浮点数
//浮点型 10.5
//整型 10
//字符 A
看了上面的数据类型,很容易看出来下面的关系:
为什么叫浮点数?
就像66.6
和6.66*10
,小数点是可以浮动的,所以叫浮点数
那么,为什么会有上面这么多的类型呢?我们就需要先回答一下下面这个问题:
每一种类型的大小是多少?
我们等一下用代码问一下他们各自的大小
先了解一下新的东西
#include<stdio.h>
int main()
{
printf("%dn",100)//
return 0;}
这个
%d
指的是打印(输出)的格式,即整型,后面的100
是返回值,即打印的是100
,n
的意思就像enter
,空行的意思,如图:
运行结果:
100
现在来解释一下n的作用,这里用两组代码来对比一下:
第一组
#include<stdio.h>
int main()
{
printf("%dn",100)//
printf("%dn",100)
printf("%dn",100)
return 0;}
运行的结果:
100
100
100
第二组
#include<stdio.h>
int main()
{
printf("%d",100)//
printf("%d",100)
printf("%d",100)
return 0;}
运行的结果:
100100100
可以看出,n的作用就是空一行,就是平时enter的作用
接下来就是
#include<stdio.h>
int main()
{
printf("%d ", sizeof(char));
printf("%d ", sizeof(short));
printf("%d ", sizeof(int));
printf("%d ", sizeof(long));
printf("%d ", sizeof(long long));
printf("%d ", sizeof(float));
printf("%d ", sizeof(double));
return 0;
}
运行结果:
1 2 4 4 8 4 8
(那么这些数字的含义是什么?它们又是怎么来看出所占内存的大小呢?我们等一会儿就来解释。)
这里的sizeof()
的作用就是返回数据类型中的char
在内存中所占的大小,通俗点就是用它来告诉你char
这个数据类型占多少内存
不过这里用%d
不太合适,在一些的编译器里面会报警告,我们用%zu
最合适,sizeof
的返回值要用%zu
来打印。
int main()
{
printf("%zun", sizeof(char));
printf("%zun", sizeof(short));
printf("%zun", sizeof(int));
printf("%zun", sizeof(long));
printf("%zun", sizeof(long long));
printf("%zun", sizeof(float));
printf("%zun", sizeof(double));
return 0;
}
结果跟上面那个图是一样的,运行结果是:
1
2
4
4
8
4
8
(我里面加了n
,所以是一排一排的)
接着我们来讲上面那些数字的含义,
你只看到了它们这些数字,但没有单位,其实它们都是有单位的,这里我们就来了解一下计算机的单位:
计算机的单位从大到小就是PB,TB,GB,MB,KB,byte
。就像我们平时生活中用的流量,一般开通的套餐只到GB
,所以GB
,MB
,KB
这些我们都已经很熟悉了,下面就是各单位间的换算
1Pb=1024Tb
1Tb=1024Gb
1Gb=1024Mb
1Mb=1024kb
1kb=1024byte(字节)
1byte=8bit(比特位)
看到这些,你可能对这些没有什么概念,我们再来进一步了解一下
我们都知道计算机使用的是
二进制
语言,而我们生活在十进制
的世界,
来给一个空间| |
,里面可以填1
或0
就是|1|
或|0|
,这就是一个bit
,对应的就是灯亮和灯灭
那么一个字节
byte
呢?
|1| |0| |1| |0| |0| |1| |0| |1|
占了8个空间,也就是8个bit
10100101
对应的十进制就是 165
一个字节能储存多大的数字呢?
11111111
对应的十进制
就是255
,即最多可以储存2^8-1
这么大的数
我们可以感受到越到后面的单位大小越庞大
解释完计算机的单位,我们就来回到上面的
1 2 4 4 8 4 8
,它们的单位都是字节
char
对应1字节,可以开辟一个能储存2^8-1
的空间
short
对应2字节,可以开辟一个能储存2^16-1
的空间
int
对应4字节,可以开辟一个能储存2^32-1
的空间
long long
对应8字节,可以开辟一个能储存2^64-1
的空间
里面的
float
和double
是来存储小数的,双精度浮点数比单精度浮点数精度要高一点,这个在以后的博客会更加深入的去讲解
但是我们看到
int
和long
为什么都是4呢?
C语言规定,sizeof(long)
>=sizeof(int)
就行,但不会超过sizeof(long long)
那么我们回到前面提出的问题,为什么要规定这样的数据类型呢,答案是节省空间:
给你一个数2
,你要把它存起来,你用了long long
这个数据类型,开辟了能储存2^64-1
的空间来放这个2
,是不是有点大材小用了,用一个char
就行了,提高空间的利用率
接下来我们来解释一下下面的代码,来引入下一个博客讲的变量和常量
#include<stdio.h>
int main()
{
int age=18;
double weight=16.5;
return 0;
}
int age=18;
向内存申请一个int
大小的空间,来把18
这个数据放在age
这个变量里面,通俗一点就是,int
要了一个房间,起名为age
(随便起名),把18
放到了里面。
double weight=16.5;
这个像上面一样,double
是数据类型,weight
是个变量,16.5
是个小数
这些数据类型就是来定义变量的
✨5. 变量和常量
跳转到目录末尾
生活中有一些是可变的量(比如你的年龄,身高,体重,对象)
还有一些不变的量(比如圆周率,性别,身份证号码)[哎,这里你说性别可变啊,我们只能笑一下,哈哈]
✨5.1变量
✨5.1.1定义变量
跳转到目录末尾
#include<stdio.h>
int main()
{
int a=10;
printf("a=%d",a);
return 0;
}
运行的结果:
a=10【a
就是一个变量(int
定义一个变量a
,向内存申请一个空间给a
,并赋予a
一个值),因为a
是可变的,所以可以赋予a
任意一个值】
下面再来多写几个变量来加深一下了解
#include<stdio.h>
int main()
{
short age=20;//年龄
int high=180;//身高
float weight=88.5;//体重
return 0;
}
运行的结果:
(因为没有printf
来输出,所以什么也没有)
可以看出来我们定义的变量
age,high,weight
分别都有自己的含义,这可以让我们在写代码时具有很好的可读性,当然变量是可以随便命名的,比如也可以把age
改为a
,无所谓,只是为了可读性。
✨5.1.2变量的分类
跳转到目录末尾
变量分为局部变量和全局变量,下面我们来用代码来演示一下
#include<stdio.h>
int global=2022;//全局变量
int main()
{
int local=2018;//局部变量
//下面的global和上面的global会不会冲突呢?
int global=2021;//局部变量
printf("global=%d",global);
return 0;
}
运行的结果:
global=2021(运行的结果为下面的global
,所以当局部变量和全局变量同名时,局部变量优先使用,所以不会冲突)
在int main() { }
外的global
就是全局变量,整个项目都可以使用的变量,在{}里面的变量就是局部变量,只能在{}
范围内使用,假如{}
中还有一个{}
可以类推全局变量和局部变量的关系,都是一样的
✨5.1.3变量的使用
跳转到目录末尾
#include <stdio.h>
int main()
{
int num1 = 0;
int num2 = 0;
int sum = 0;
printf("输入两个操作数:>");
//输入两个数
scanf("%d %d", &num1, &num2);
//求和
sum = num1 + num2;
//输出sum的值
printf("sum = %dn", sum);
return 0;
}
//这里介绍一下输入语句
//scanf可以输入数值赋予后面&所带的的变量num1和num2
在你运行的时候会出现下面的情况:
不要害怕,出现的错误在错误列表上会显示出来(但不要太依赖这个,仅供参考,很多时候出错的莫名奇妙):
错误 C4996 ‘scanf’: This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS.
我们来慢慢解析一下,它说,这个
scanf
它不安全,让你使用它的替代品scanf_s
,如果你执意要使用scanf
,需要在前面加一个_CRT_SECURE_NO_WARNINGS
我们这里来说一下scanf_s
,它是vs编译器自带的只能在这个编译器里使用,只有这个编译器认识它,所以我们应该使用的通用的scanf
,但是使用scanf
它会报错啊,来,我们往前面加一个#define _CRT_SECURE_NO_WARNINGS
试一试
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int num1 = 0;
int num2 = 0;
int sum = 0;
printf("输入两个操作数:>");
//输入两个数
scanf("%d %d", &num1, &num2);
//求和
sum = num1 + num2;
//输出sum的值
printf("sum = %dn", sum);
return 0;
}
运行结果:
输入两个数,中间用空格隔开
按enter
即可输出两数之和
可以看出来,这串代码可以运行了,那么我们每次使用scanf
就要每次都加一个#define _CRT_SECURE_NO_WARNINGS
是不是太麻烦了,告诉你们一个办法:
在vs的安装路径下有一个文件
newc++file.cpp
,
在vs工程中创建新的.c
或.cpp
文件的时候,都是拷贝上面这个文件的,所以我们只需要把这个文件的开头加上#define _CRT_SECURE_NO_WARNINGS
,之后所创建的.c
或.cpp
都会带有#define _CRT_SECURE_NO_WARNINGS
✨操作:
✨下载everything
(下载链接在下面的百度云)
✨打开everything
✨查找newc++file.cpp
✨用记事本打开
✨把#define _CRT_SECURE_NO_WARNINGS复制在里面
保存即可,之后我们创建的新项目里面都会包含这条代码,也就不需要一直输入#define _CRT_SECURE_NO_WARNINGS
✨5.1.4 变量的作用域和生命周期
✨5.1.4.1 作用域
跳转到目录末尾
作用域(scope)是程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效/可用的
而限定这个名字的可用性的代码范围就是这个名字的作用域。
- 局部变量的作用域是变量所在的局部范围(就是局部变量所在的{})
- 全局变量的作用域是整个工程。
我们举一个全局变量作用于整个工程的例子:
文件test4.5(2),里面的int a=100就是一个全局变量
另一个项目test4.5里面
运行的时候出现了错误,原因是没有申明这个变量a是来自其他项目里面的
所以我们加了一个
extern int a;//去申明一下它来自外面
这时去运行一下,结果:
a=100,没有问题
✨5.1.4.2 生命周期
生命周期就类似于作用域,类比过来就行,生命周期≈作用域
变量的生命周期指的是变量的创建到变量的销毁之间的一个时间段
- 局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。
- 全局变量的生命周期是:整个程序的生命周期。
✨5.1.5 变量的命名:
1.????有意义????
int age;
//年龄
float salary;
//薪资
2.????名字在必须是字母、数字、下划线组成
不能有特殊符号,同时不能以数字为开头????
int 2b;
//err
int _2b;
//ok
3.????**变量名不能是关键字**????
✨5.2常量
跳转到目录末尾
生活中有一些是可变的量(比如你的年龄,身高,体重,对象)
还有一些不变的量(比如圆周率,性别,身份证号码)[哎,这里你说性别可变啊,我们只能笑一下,哈哈]
✨5.2.1 常量的定义
跳转到目录末尾
常量就是一个不变的量(比如圆周率,性别,身份证号码)
C语言中的常量和变量的定义的形式有所差异。
✨5.2.2 常量的分类
跳转到目录末尾
C语言中的常量分为以下以下几种:
1.字面常量
2.const 修饰的常变量
3.#define 定义的标识符常量
4.枚举常量
我们来演示一下
✨5.2.2.1 字面常量
跳转到目录末尾
就是字面上就可以看出来的常量
int main()
{
//字面常量演示
3.14;//小数
1000;//整数
'w';//字符
"abc";字符串
return 0;
}
✨5.2.2.2 const修饰的常变量
跳转到目录末尾
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>//使用printf记得加这条代码
int main()
{
//const修饰的常变量演示
int a=100;//我们等一会儿会改变它
a=10;
printf("%d",a);
return 0;
}
运行结果:
10
当我们在int a=100前加一个const来修饰
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
//const修饰的常变量演示
const int a=100;//在这儿
a=10;
printf("%d",a);
return 0;
}
运行的结果:
出错了
我们可以知道,const如果修饰一个变量,再给变量换一个值是不被允许的,相当于一个常量,但它还有变量的属性,所以我们就叫它是const 修饰的常变量
为什么说它具有变量属性呢?
我们来证明一下:
再新了解一个东西,数组,当我们来写代码的时候,有时候需要写很多的变量,很麻烦,这时候我们使用数组arr[ ],(a[ ],hin[ ]都随便,自己起一个名),在数组的[ ]中只能放常量,比如arr[5],相当于你直接定义了5个变量,里面是不能放变量的,根据这个原理我们来证明一下const 修饰的常变量是否具有变量属性
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
const int a = 100;
int arr[10] = {0};
return 0;
}
可正常运行
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
const int a = 100;
int arr[a] = {0};
return 0;
}
运行结果:
出现了错误,说明const 修饰的常变量具有变量属性
我有一个大佬(我认为的大佬,哈哈哈)是这样理解的:假设变量是一个空间,常量是一个实际值,变量用来容纳常量,const只是锁定了值,但是并不是把空间变成数值
✨5.2.2.3 #define 定义的标识符常量
跳转到目录末尾
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#define MAX 100//here
int main()
{
printf("%dn",MAX);
int a=MAX;
printf("%dn",a);
return 0;
}
运行的结果:
100
100
可以看出来,MAX被定义为了100,无论是直接打印还是给变量一个值都可以,想用的时候就可以拿出来使用,这个MAX就是标识符常量,也就是#define 定义的标识符常量。(#define也是可以定义一个字符串的,不局限于数字)
✨5.2.2.4 枚举常量
跳转到目录末尾
我生活中一些值是可以一一列举出来的,比如性别,我们初步来了解一下,毕竟只是初始c语言,
#include <stdio.h>
enum Sex
{
MALE,//男
FEMALE,//女
SECRET//不确定
};
//enum Sex未来的可能取值就是MALE,FEMALE,SECRET,它们三个就是枚举常量
int main()
{
//枚举常量演示
printf("%dn", MALE);
printf("%dn", FEMALE);
printf("%dn", SECRET);
//注:枚举常量的默认是从0开始,依次向下递增1的
注意,这里enum Sex里面三个枚举常量并不开辟空间,而且也是不能改变的,改变就会报错
????6. 字符串
跳转到目录末尾
这一篇博客我们来了解一下字符串,看下面这个我们熟知的也是最先学习的代码
"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("%sn",arr1);
printf("%sn",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("%sn",arr1);
printf("%sn",arr2);
return 0;
}
运行的结果:
abcdef
abcdef烫烫烫烫烫abcdef
哎,发现没有,它们不一样了,那为什么会出现这种情况呢?
先想一个问题,它是根据什么来停止打印的?
(啊,你会问:它们后面啥都没有,我怎么会知道它们根据什么来停下来的)
那里确实看不见有什么标志,但是那个标志就是看不见的,字符串的结束标志是 ,它是一个我们马上就会学到的转义字符
char arr1[]="abcdef";
这个形式一,字符串后面就默认带了一个
char arr2[]={'a','b','c','d','e','f'};
这个形式二,后面没有
懂了吧,printf去打印的时候要识别到 才会结束
第一个形式最后一个字符结束就识别到了 ,然后结束
第二个形式识别到最后的f,一直都没有识别到 ,就一直打印下去,最后就出现刚才的结果
那么如果我们给第二个形式加一个 作为结束标志怎么样,不要光想,我们来做一下试试
#include<stdio.h>
int main()
{
char arr1[]="abcdef "; //我们也试一下给它也加一个
char arr2[]={'a','b','c','d','e','f','