C生万物 | 底层之美,莫过于C【上】

举报
烽起黎明 发表于 2023/02/20 12:03:46 2023/02/20
【摘要】 100多张详细图示指导,十六个C语言重要大点,带你从0开始学习C语言,走上编程这条不归路

:ship:写在前面:ship:

  • 点开这篇文章后,可能你是刚学习编程的萌新,或者是已经学习了一两门语言的编程入门者,又或者是面对满屏Bug无从下手的老司机。无论你是何身份,此时我想问你一个问题?

你,真的熟练掌握C语言吗?

  • 我想你心里已经有了一个答案,从今年的开始,我将重新学习C语言,去细究底层的原理,在此基础上打牢计算机基础,为自己建立一个扎实的根基。所以,无论你基础如何,在【万物之源——C】这个专栏,我都将一步步,带你扎扎实实地学习,掌握好每一个知识点,也希望能够==带你从小白到大神熟练掌握C语言==

在这里插入图片描述
@TOC

一、什么是C语言

C语言是一门通用的【计算机编程语言】,广泛地应用于==底层开发==。C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。

  • 上面提到了这个底层开发,我们经常会听到这个上层应用开发和下层应用开发,这个到底怎么区分呢?
  • 我们通过下面这张图来看一下

在这里插入图片描述

  • 可以看到,对于像C/C++这样的语言,适合于底层应用的开发,例如说是服务器、嵌入式之类的;而像一些上层应用的开发,就要用到现在很流行的Java语言,就很适合上层应用的开发
  • 那C/C++就不能开发上层应用了吗?当然不是,只是对于下层应用的涉及会广泛一些而已,像C++也是一门面向对象的编程语言,也可以用来开发一些上层应用

接下来我们再来讲一下这个C语言的标准都有哪些

  • 首先,C语言最初的标准,就是美国国家标准局为C语言制定了一套完整的美国国家标准语法,称为==ANSI C==
  • 然后在2011年12月8日,国际标准化组织(ISO)和国际电工委员会(IEC)发布的==C11标准==是C语言的第三个官方标准,也是C语言的最新标准,该标准更好的支持了汉字函数名和汉字标识符,一定程度上实现了汉字编程

二、第一个C语言程序

1、逐步教学

了解了什么是C语言之后,我们就要使用C语言来进行编程,那C语言的主要编译器有哪些呢?

  • 其编译器主要有Clang、GCC、WIN-TC、SUBLIME、MSVC、Turbo C等。
  • 我们在之后所写的代码都是在MSVC,也就是微软推出的VS2019上运行,当然VS2022也是可以的,只是刚刚发布可能有些地方会有Bug没修复,但是2019的话已经是经过了一段时间的沉淀,已经属于是比较稳定的了:snail:

好,首先我们来看看如何去创建工程,来编写我们的第一个C语言程序

  • 首先,打开VS2019,看到右下角有一个创建新项目,点进去即可

在这里插入图片描述

  • 然后的话你需要选择左侧的空项目,右侧也是,默认第一个,接着在上面选择C++,当然,如果你编写其他程序的时候也可以选择其他程序语言
  • 接着点击下一步

在这里插入图片描述
在这里插入图片描述

  • 然后我们进入这个配置新项目中,修改其保存的位置,不要去使用默认的,然后这个项目名称也最好不要使用中文,当然你为了可以方便阅读项目也可以写
  • 好,接下来我们点击创建,就会自动给我们在D盘的C文件夹中自动创建一个工程

在这里插入图片描述

  • 然后旁边会有这么一栏【解决方案资源管理器】,这里可以去管理我们创建出来的.h【头文件】和.c【代码文件】
    在这里插入图片描述
  • 但是有同学说,啊呀,我这个解决方案资源管理器找不要了,怎么办呢,这个时候不要急,也是后办法的
  • 这个时候我们只要找到【菜单栏】里的【编辑】,然后就可以看到我们的解决方案资源管理器课,或者你记住个快捷键【Ctrl + Alt + L】也是可以的

在这里插入图片描述

  • 知道如何打开解决方案资源管理器后,接下来我们就要去创建存放代码的文件了
  • 选择右击源文件,然后选择添加——新建项

在这里插入图片描述

  • 然后在这里要选择上面的.cpp文件,因为这是C/C++的编译器,然后文件名称的地方选择.c的后缀,这是C语言的源文件后缀,.cpp是C++的

在这里插入图片描述

  • 然后我们写上main函数测试一下,打印一句话,点击上方的【本地Windows调试器】或者是按Ctrl + F5,就可以先调试控制台【终端】,也就是我们常说的小黑框框打印出这句话

在这里插入图片描述

  • 这就是我们所写出的第一个C语言程序

2、扩展与疑难分析

  • 这是打印的一句代码,现在我将这句代码多复制几份,然后打印输出,大家看一下
  • 可以看到,这个代码被输出了好几行,那这个时候就有同学疑问,这是为什么呢?这个输出是什么原理呢?

在这里插入图片描述

  • 这个时候我们就可以进行一个【调试】,点击菜单栏中的【调试】,然后进入看到有一个开始调试和开始执行【不调试】,后者也是我们上面运行代码的第三种方式
  • 然后前后就是我们调试的进入命令,而且还可以直接按快捷键【F5】,若是笔记本的话,如果安不了就按【Fn + F5】,进入调试

在这里插入图片描述

  • 但是在调试之前不要忘了在你的代码左边,也就是这个数字左边点一下,就会出现一个小红点,这个小红点表示你运行代码就是默认调试
  • 然后我们进入调试

在这里插入图片描述

  • 然后就可以看到这个小红点里面多了一个小箭头,这个就是调试所要用到的【逐步语句箭头符号】

在这里插入图片描述

  • 这个时候我们按下【F10】,就可以让代码一句句地往下走,叫做【逐语句】若是你按下【F11】,就可以进入一个你封装过的函数,叫做【逐过程】,这个我们后面在==调试的时候==再做详细的讲解

  • 那这个时候又有同学说了,这个main是什么东西呀,我不认识这个?
  • 我们现在来讲一下这个main是什么
  • 对于这个miain,我们管它叫做main函数,是我们运行程序的主函数入口,所有要在终端显示的内容都要放在此处运行才可以被看到。当然再后面我们还会说到【函数】,你可以将一个单独的功能封装成为一个函数,然后在这里调用函数传参即可
int main(void)
{
	printf("Hello Bit\n");
	printf("Hello Bit\n");
	printf("Hello Bit\n");
	printf("Hello Bit\n");
	printf("Hello Bit\n");
	return 0;
}
  • 然后我们缩写的代码就叫做【函数体】,
  • 这个int叫做函数返回类型,return 0是函数的返回值,这两个要相互对应,不可以函数返回类型是整型,但是返回的是一个字符类型

  • 而且尤其要注意的一点是,这个main函数只能有一个,而不能有多个,我们来试试写多个mian函数会出现什么结果
  • 很明显可以看到,说到【此main函数已有主体】
  • 所以我们在撰写main函数的时候要记住不可以写多个,只能写一个

在这里插入图片描述


  • 那这里有同学又说了,大体的框架我是知道了,但是这个【printf】是什么意思呀,我还是不懂?那我们再来说一说
  • 【printf】是我们在C语言里面的输出语句,那有输出一定是有输入,它叫做【scanf】,这个我们在后面也会详细说到,他们叫做【输入输出流】,都存在于一个头文件中,这个头文件叫做【stdio.h】,所以我们应该要在程序的开头写上这个包含头文件的代码,这样你才可以使用这个头文件里的内容
#include <stdio.h>

三、数据类型

写出了我们的第一个C语言程序,接下来我们来说一说C语言中的数据类型

  • 首先我们为什么要写代码呢?那就是为了解决生活中的问题

  • 比如说我们在购物软件购物的时候,买到商品的价格可能是整数,也可能是小数,而且这个商品的平常在后台也是一种“字符串”的类型,这么多的种类,要怎么区分呢?这个时候我们引入了一个东西——【数据类型】

  • 我们先来整体地看一下C语言中有哪些数据类型,下面就是

在这里插入图片描述

  • 那对于这些数据类型,它们的大小是多少呢?
  • 我们使用【sizeof()】这个运算符来看一下
printf("%d\n", sizeof(char));
printf("%d\n", sizeof(short));
printf("%d\n", sizeof(int));
printf("%d\n", sizeof(long));
printf("%d\n", sizeof(long long));
printf("%d\n", sizeof(float));
printf("%d\n", sizeof(double));

在这里插入图片描述

  • 从上述运行结果我们可以清楚明了地看出来,那有同学又说这个1,4,8的单位是什么呢?
  • 我来告诉你,它们的单位是B【字节】,在计算机里1B = 8b,这是一种十进制写法

  • 那为什么会出现这么多类型呢?它们是用来干嘛的?

刚才我们有说到过,因为生活中每种事物、每种东西都是不同的,它们的数据类型都不同,那么这个时候,为了满足多种需求,就要给出多种数据类型。这也就==更加丰富的表达生活中的各种值==

  • 就像我们在下面定义的这些变量,有char类型的,有int类型的,也要double类型的
char ch = 'w';
int weight = 120;
double salary = 200.00;

四、变量与常量

1、变量的命名规则

对于变量,并不是可以随便命名的,而是具有一定的规则,接下来我们来看一下具体有什么规则

  • 只能由字母(包括大写和小写)、数字和下划线( _ )组成
  • 不能以数字开头
  • 长度不能超过63个字符
  • 变量名中区分大小写的
  • 变量名不能使用关键字

然后我们再来具体讲一下

  • 首先第一条,字面意思,很明确,就是需要用着三种东西来组成变量,可以不包含它们所有,但是其他的字符就不可以
  • 我们可以从下面这张图很清晰地看出来

在这里插入图片描述

2、变量的分类

对于变量,可以分为==全局变量和局部变量==

  • 这样不好说,我们一起到代码里来看看
  • 从下可以看出,global是一个全局变量,而num则是一个局部变量

在这里插入图片描述

  • 然后我们看下面的这段代码,我在main函数内部又定义了一个global,然后此时我们在终端打印的时候这个global便成了50,
  • 这是为什么呢?因为局部变量的global覆盖了全局的global,可以理解为是一个优先使用的原理

在这里插入图片描述

3、变量的使用

了解了什么是变量,现在我们就要具体地去使用这个变量了,让我们一起来看看

  • 我们来看下这段代码:newspaper:
int main(void)
{
	int num1 = 0;
	int num2 = 0;

	scanf("%d %d", &num1, &num2);
	printf("sum = %d\n", num1 + num2);

	return 0;
}
  • 这是一个求和的功能,scanf的话就是我们上面所说到的【输入流】
  • 接着我们再来看一下下面这段代码

在这里插入图片描述

  • 可以看到,程序报出了错误,大家去试一下的话也是会这样,这是程序报出的一个运行错误,建议我们使用【scanf_s】这个来进行输入,但是可以对于这个【scanf_s】,它是VS里自带的输入流函数,若是放到其他平台上去就运行不了了,而【scanf】则是一个C语言的一个输入函数
  • 但是大家仔细看我用箭头指向的这段,这也是编译器提供给我们的第二种解决方案,然后我们需要在整个程序的开头使用【#define】去给出这么一个文件定义,保证后面不会进行报错
  • 最后还要加上一个【1】,不要忘记了
#define _CRT_SECURE_NO_WARNINGS 1

Everything

  • 上面这个链接是干嘛的呢,对于这个定义,若是每次新建一个文件就重新敲一次,那是不是显得很麻烦,这个时候我们就有了一个快捷的办法,就是直接在VS2019的一个叫【newc++file.cpp】里面添加上这句定义,这样你每次新建一个源文件时就不需要去再打这个代码了
  • 具体怎么操作呢,很简单,你只要点进我的这个链接,下载一个这个工具,然后在这个搜索框内输入newc++就可以看到这个文件,接着右击【打开路径】即可
  • 在你安装VS的地方会有这个文件,然后用【记事本】的方式打开,将我上面这句代码写进去就行,然后你可能会失败,因为要管理员的权限才能修改内容
  • 这时候你只需要将这个文件复制到桌面,然后一样修改便可,接着再拷贝回去,然后在你的编译器里新建一个源文件测试一下即可

在这里插入图片描述

  • 这里可以看到,我们新建一个add.c,就可以看到默认出现了这个定义

在这里插入图片描述

4、变量的作用域和生命周期

清楚了如果使用变量去编写程序,接下来我们来了解一下==变量的作用域和生命周期==

作用域

作用域(scope)是程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效/可用的而==限定这个名字的可用性的代码范围==就是这个名字的作用域

  • 了解了其基本概念,我们就到代码中来演示一下
  • 可以看到,我们下面是写了一个代码块,然后里面定义了一个变量a,然后将其打印
  • 接着在代码块的外层也打印了这个a,但是可以看到,程序报出了错误,说【未定义标识符】,所以可以看出这个作用域是具有限定范围的

在这里插入图片描述

  • 以上的话就是局部变量的作用域,既然局部变量有作用域,那么全局变量也拥有作用域
  • 从下面代码可以看出,完全没有报出错误,因为对于全局变量的作用域,是从定义变量开始到整个程序运行结束,整个变量才会被销毁,而这个变量a,则是在这个代码块结束之后便会销毁,所以我们在后面才访问不到这个变量

在这里插入图片描述

  • 对于全局变量的作用域,我们还可以这么来看,把这个b变量定义在add.c这个文件下,然后我们在test.c这个文件定义一下这个变量b,用这个extern关键字声明一下即可,表明这个是一个外部变量

在这里插入图片描述

生命周期

变量的生命周期指的是变量的创建到变量的销毁之间的一个时间段

  • 对于生命周期这个概念还是比较抽象的,它不是一个范围,而是一个时间段,就我们上面的代码看来,这个变量a,它的生命周期也就是从它在这个代码块定义开始到这个代码块结束,这就是它的生命周期

局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。

全局变量的生命周期是:整个程序的生命周期

5、常量的种类

讲完了变量,接下去我们来讲讲常量

常量的定义形式和变量有所区别,在C语言中,常量一般分为以下几种

  • 字面常量
  • const 修饰的常变量
  • #define定义的标识符常量
  • 枚举常量

我们到代码中来看一下

//字面常量 - 直接写出来的这种数字
3.14;
100;

//const修饰的常量
const float PI = 3.14f;
PI = 6.18;	//error -  常量不可直接修改

//#define的标识符常量 
#define MAX 100
printf("max = %d\n",MAX);	//这里的MAX也属于常量
  • 看完了上面三种常量的表示形式,我们再来看最后一种枚举的形式【枚举在后面会细讲】

  • 假设我们现在要定义一个性别的枚举体,然后里面有三种

enum Sex {
	MALE,
	FEMALE,
	SECRET
};
  • 然后我们来输出一下这些枚举体中的变量
int main(void)
{
	printf("%d %d %d\n", MALE, FEMALE, SECRET);

	//MALE = 3;		常量,不可修改
	return 0;
}
  • 可以看到,输出的是0 1 2,因为在枚举体中,默认是从0开始,然后依次递增
  • 但是这可以修改吗?当然可以,比如说,你可以把MALE定义成为 = 4,这样后面输出的便是4 5 6,也是呈现一个依次递增的结果

在这里插入图片描述

  • 然后我们对枚举体中的内容进行修改的时候,程序报出了错误,这就是因为枚举体中的内容全都是常量的原因,因此是不可以修改的

六 、字符串

1、概念

在讲完常量之后,我们来讲一讲字符串

  • 在讲字符串之前,我们先来看看下面这个,因为在计算机中存储、表示的都是二进制,所以我们打印出来的也会是一个二进制
  • 首先定义一个char类型的字符变量ch,然后分别以%c、%d、%s去打印出来,可以看到,显示的结果各不相同
  • %c打印的就是一个字符,%d打印的则是这个字符在ASCLL码表中的值,最后的%s,我们打印的就是ch这个==字符串==

在这里插入图片描述

  • 然后我们便开始讲一讲字符串

概念:双引号引起的一串字符叫做字符串

  • 所以无论是多个字符还是单个字符,又或者是无字符,但只要是在双引号内部的,都可以叫做是字符串
int main(void)
{
	//"zhangsan "
	//"a"
	//""
}

2、求解字符串的长度【strlen】

说完了字符串了基本概念,了解了什么是字符串,接下去我们来看看如何入求解字符串的长度

  • 对于字符串,大家要知道,结束标志是一个 ==\0== 的转义字符,转义字符我们下个模块就讲到,这个\0表示这个字符串已经结束了。但是在计算字符串长度的时候,这个\0是不计算在内的
  • 也及时说,求字符串的长度统计的是字符串中\0之前出现多少个字

那我们如何去求解一个字符串的长度呢?

  • 这里我们需要使用到一个string.h头文件里的一个函数,叫做strlen(),可以计算一个字符串的长度,也就是\0之前的长度,这个函数我们后面会细讲
printf("len = %d\n", strlen("abc"));	//a b c \0

在这里插入图片描述

  • 可以看到,长度为三,求的是\0之前的长度,但是这样看不太明显,我们再来看一个👀

在这里插入图片描述

  • 可以看到,我们手动加上了一个\0,输出的len长度还是3,所以\0后面的def是没有被算进去的

前面我们说到过char类型可以定义一个字符变量,不仅如此,在这里,我们还可以定义一个字符数组,什么是字符数组呢?就是这个数组中存放的都是字符,我们来看一个具体的定义

char arr[] = "abcdef";
  • 以上就是字符数组的基本定义
  • 接着我们再来看一种,下面这一种也是字符数组的定义方式
char arr2[] = { 'a','b','c','d','e','f' };
  • 可以看到,这两个字符数组中的内容是一样,那他们打印出来,以及计算出来的长度是否是一样的呢,我们一起来看一下

在这里插入图片描述

  • 很明显,从以上结果来看,是不一样的,这是为什么呢?我们通过一张图示来了解一下

在这里插入图片描述

  • 从以上这张图我们应该可以很明显地看出来,为什么第二个arr2数组在打印的时候会出现【烫烫烫】这种东西呢,如果你自己去编译器里试试的话应该也是这样
  • 因为第二个数组的内容值给到了’f’,并不是一个完整的字符串,但是第一个数组给到的却是一个完整的字符串,所以自动拥有一个’\0’,第二个数组就没了,所以后面打印出来的只会是一个随机值,然后直至碰到一个\0为止,遍历才会结束
  • 所以我们可以看到这个长度也是受到了影响,arr1数组的长度就是6,但是arr2数组的长度却是加上了一些随机字符后的长度,这就显得不准确了

3、转义字符【含面试题】

好,接下来我们再来说一个东西叫做什么呢?叫【转义字符】

  • 那什么叫做转义字符呢?我们通过代码来看看
int main(void)
{
	printf("abcndef");
	printf("abc\ndef");
}

在这里插入图片描述

  • 通过运行结果我们可以看到,这个n,若是在其前面加上了一个\,则它的意思就发生了变化,在转义字符里面就叫做【\n换行】,所以可以看到打印到【abc】就发生了换行,在后一行打印了def

  • 然后我们再来看到一个打印一个test.c的路径,但是呢,从运行结果来看,并没有真正地打印出来一个路径,而是出现了很多空格,这是为什么呢?
  • 细心的小伙伴应该可以发现这个test的第一个字符t和路径的\是同一个颜色,都淡化了,在转义字符里,这个叫做【\t水平制表符】,也及时们键盘上的【Tab键】,敲一下就能空出4个空格

在这里插入图片描述

  • 所以我们在printf输出一个东西的时候,不要去写一些转义字符,那C语言中有哪些转义字符呢,我们一起来看一下
  • 用一个表格给大家呈现:bar_chart:
转义字符 释义
? 在书写连续多个问号时使用,防止他们被解析成三字母词
\ ’ 用于表示字符常量
\“ 用于表示一个字符串内部的双引号
\ \ 用于表示一个反斜杠,防止它被解释为一个转义序列符
\a 警告字符,蜂鸣
\b 退格符
\f 进纸符
\n 换行
\r 回车
\t 水平制表符
\v 垂直制表符
\ddd ddd表示1~3个八进制的数字。如:\130X
\xdd dd表示2个十六进制数字。 如:\x30 0
  • 我们挑重点的说一下
  • 首先是二三两个,看第一行代码,若你printf的是一个【’’’】,那么编译器就会报错,你本是想打印一个【’】,这个时候该怎么办呢,你只需要在前面加上一个\,这就变成了一个转义字符,然后就可以像运行结果一样输出了
  • 然后第三个也是同理,这里便不做过多详解

在这里插入图片描述

  • 然后就是刚才我们所说的打印路径,要怎样才能打印出这个路径呢?没错,你只需要将【\】换成【\】就可以了,这就表示一个反斜杠,我们到代码里看一下
  • 可以看到,这个路径已经被完全打印出来了

在这里插入图片描述

  • 最后,我们再来讲一下最后两个有关八进制和十六进制的
  • 一样,先给出运行结果

在这里插入图片描述

  • 有关【\ddd】,表示的就是八进制,也就是通过八进制去计算,如果用%d打印出来的就是计算的结果,如果使用%c打印出来的就是这个数字所对应的ASCLL码符号

在这里插入图片描述

  • 对于十六进制也是同理,/xdd值就是十进制,然后看上面的打印也是同理
  • 对于【\x3a】的话就是用a*16^0^

在这里插入图片描述

  • 然后我们来说一道有关转义字符的面试题
printf("%d\n", strlen("c:\test\628\test.c"));
  • 你认为这个结果打印出来是多少,我问了很多人,答案有18、15、14、13、12、11五花八门
  • 而真正的答案是【14】,为什么呢?我们来看一下

分析

  • 首先第一步,我们刚学了转义字符,【\t】表示的一定是一个字符,所以18排除
  • 然后第二步,相信大家最疑惑的就是这个\628,这其实就是我们上面所说的\ddd,但是这都能算吗?这个时候你就要去想,八进制能包含8吗,八进制就是0~7的数字,所以是不会有8,因此这个【\62】算一个转义字符
  • 最后我们就可以得出答案为【14】

七、注释

了解了字符串,接下来我们来看看C语言中的注释

首先我们要先了解一下注释是什么,它可以用来干嘛

1、注释可以将你不需要或者还不想删除地代码暂时屏蔽起来,在程序执行的时候会直接跳过注释的代码,会不运行
2、如果在一些程序中有一些晦涩难懂的代码,可能你写出来的代码需要需要一些批注后面在阅读你代码的人才能知道这段代码是什么意思,这个时候你就可以在这段代码的上方或是下方写一些注释,这样后人就可以看懂你写的代码
对于这一点,如果大家以后在成为程序员后进入企业工作也需要养着这样良好的习惯,在一段比较难懂的代码前添加一些注释,不仅是为了后人,你自己后面也可能会去阅读你自己写过的代码,这个时候若是你有一些注释写着,阅读起代码来就不会那么累了

int main(void)
{
	//下面是创建一个整型变量并赋值10
	int a = 10;
	int b = 100;
	//C++ 注释风格 - C99

	/*	C语言的注释风格
	int c = 10;
	int d = 20;
	printf("ff");
	*/	// - 嵌套的话此处结束注释
	//不支持嵌套注释

	return 0;
}
  • 我们来分析一下,对于双斜杠//,这个是C99中对于C++的注释风格,那C语言的注释风格是怎样的呢,就是/**/
  • 但是后面我还补充了一句话,就是对于C语言的这种注释方法,不可以产生嵌套的,例如说这里若是在外层加上一个/**/,这样return 0;不会被注释了,为什么呢?因为上面的/*和return 0;上面的那个 先匹配了,所以就不会到下面的

八、选择语句

说完了注释,接下去我们来讲讲选择语句

  • 那有同学问,什么是选择语句呀?
  • 在C语言或是其他编程语言中,都有着三种结构方式:【顺序】、【选择】和【循环】,之后我们也会细讲到。对于生活中的各种事情,都可以用这三种结构方式组成或者是嵌套形成
  • 那这个选择语句是什么呢?就是你有时候会面临两种或多种选择,不同的选择对应的就是不同的结果

具体我们通过代码来看一下

int main(void)
{
	int input;
	printf("你要好好学习吗(1/0)\n");
	scanf("%d", &input);
	if (input == 1) {
		printf("拿一个好offer\n");
	}
	else {
		printf("回家种田\n");
	}
	return 0;
}
  • 上面这一段代码,就是一个选择语句,你可以在终端输入你的选择,问你要不要好好学习。若你选择的是1好好学习,那么你就可以拿一个好offer;但若是你选择0摆烂,那么就只能回家种田
  • 任何事情都取决于你的选择:point_left:

九、循环语句

然后我们再来说说另一种形式,也就是循环语句

  • 什么是循环呢?循环就是你一直不断重复地做一件事,直到某个条件满足时才会退出,比如我们作为一个学生都要日复一日地学习,大家以后走上工作岗位后要日复一日地工作:pen:
  • 然后我们通过一段代码再来看一下
int main(void)
{
	int line = 0;
	printf("好好学习\n");

	while (line < 20000)
	{
		printf("写代码:%d\n", line);
		line++;
	}
	if (line == 20000)
		printf("好offer\n");
	return 0;
}

在这里插入图片描述

  • 作为一个程序员,你一定要多写代码,这里我们给到一个循环,你一直在写代码,写一行代码这个line就++,然后直到你写到20000行代码的时候,这个循环就退出了,然后你就找到了一个好offer
  • 当然这只是举例,若是你真的像找到一个好工作,就要不断地写代码,不断地去提升自己

然后对于循环的话,不仅仅是有while,还有do…while(),for这些,我们在后续都会讲到

十、函数

接下去我们来说说函数,函数其实就是将一个功能单独封装成为一个模块,然后这个模块可以被多次调用,以便来实现代码的简化

  • 我们先来看这么一段代码
  • 这是一段两数求和的代码,输入两个数据,然后输出它们的和
  • 但是设想,若是我们要再求另外两个数的和,那么就要再次输入,然后求和的代码就要再写一遍,这就徒增了代码量,显得整个程序很冗余,那要怎么简化呢?对就是使用函数
int main(void)
{
	int num1 = 0, num2 = 0;
	int sum = 0;
	printf("请输入两个操作数字\n");
	scanf("%d %d", &num1, &num2);

	sum = num1 + num2;
	printf("sum = %d\n", sum);
	return 0;
}
  • 我们来看一下使用函数简化完之后是什么样子
  • 你不要看这段代码很长的感觉,但是我使用了三次求和,得到了三个求和结果
int Add(int m, int n)
{
	return (m + n);
}
int main(void)
{
	int sum1 = 0;
	int sum2 = 0;
	int sum3 = 0;

	sum1 = Add(1, 2);
	sum2 = Add(5, 7);
	sum3 = Add(4, 9);

	printf("sum1 = %d\n", sum1);
	printf("sum2 = %d\n", sum2);
	printf("sum3 = %d\n", sum3);
	return 0;
}

在这里插入图片描述

原理剖析

  • 可能还有同学对这个函数是如何传参调用的不太了解,我们通过图示来看一下

在这里插入图片描述

  • 我们假设是看到的是一个工厂,工厂都要进原料,然后在工厂内部加工然后才能生产出一个个产品
  • 然后将这个工厂映射为函数,这个原料其实就是我们所传入的实参,工厂内部会有人来接应这个原料然后送到对应的地方,这个就是形参,然后呢,将其送入到工厂内部加工,就是在函数内部对传入的形参进行相应的操作,然后这个返回值其实就是加工完之后的产品,它会进行一个返回,在主函数体里接收一下即可

在这里插入图片描述

  • 上面就是我们对这个函数体的剖析:point_up_2:

十一、数组

1、数组的定义

好,说完了函数,我们的内容也就讲了60%了,接下去我们来谈谈数组

  • 首先我们知道数字这个概念,但是当我们需要一堆的数字,那么这个数字存到哪里去呢?没错,也就是用一个叫【数组】的东西存放起来
  • 那要怎么存放呢,我们来看一下
int a[10] = { 1,2,3,4,5,6,7,8,9,10 };
  • 首先你需要先声明这个数组是什么类型的,是整型、字符型还是浮点型等,数组的话这些数据都是可以存储的,然后在一个变量后面加上一个[],括号里可以写上你准备为这个数组开辟多大的空间,比如说上面写的是10,那么这个数组中最多能存下的数据也就只有10个,但是若你不写的话,就可以存多个,后面会教大家一个方法去计算没有给出数据具体大小如何去求这个数组的大小
  • 这里先给出,大家可以先看看,sizeof()是一种单目操作符,是用来计算你所使用的操作数所占的空间字节大小
int sz = sizeof(a)/sizeof(a[0]);
  • 刚才说过,数组除了可以存放整数数据外,还可以存放字符型、浮点型的数据
char b[] = { 'a','b','c'};
double c[] = {2.5,6.9,7.7,1.5 }

2、数组的下标

知道了数组怎么声明,那我们声明的这些数组怎么获取到呢?

  • 没错,我们要通过下标去
  • C语言规定:数组的每个元素都有一个下标,下标是从0开始的访问。下面就是我们通过下标去访问的a数组中下标为8的元素,打印出来的就会是9
//下标访问数组元素
printf("%d\n", a[8]);
  • 具体大家看图示就能一目了然了:page_with_curl:
    在这里插入图片描述
  • 可以看到,这里arr数组的大小是10,那我们去访问18这下标会怎么样呢,去编译器里看看👀
  • 从图中可以看出,总共下标也就只有9,你访问到了,那就会产生越界访问,那么你访问到的就会是一个随机值

在这里插入图片描述

3、数组的使用

了解了数组该如何定义,清楚了可以通过下标去访问数组,接下来我们来看看数组究竟如何使用

  • 看一下代码。我们首先定义了一个大小而10的整型数组,然后将其内容初始化为0,然后我们通过一个在while循环中通过scanf去输入一些数据,将其一一地通过下标放入数组中。然后呢,还是一样,通过循环去遍历这个数组,调用printf去打印出里面的数据
  • 这就是数组的一种使用方法,其余的我们放到后面==数组章节==细讲
int main(void)
{
	int arr[10] = { 0 };
	//0 ~ 9 - 输入10个值给数组
	int i = 0;
	while (i < 10) {
		scanf("%d", &arr[i]);
		i++;
	}

	i = 0;
	while (i < 10) {
		printf("%d ", arr[i]);
		i++;
	}
	return 0;
}

后序请见【下】

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。