查看: 135|回复: 1

零基础C语言自学教程(1)——初步认识C语言的全部知识框架 ...

[复制链接]

4

主题

8

帖子

18

积分

新手上路

Rank: 1

积分
18
发表于 2023-2-11 13:40:23 | 显示全部楼层 |阅读模式
学习C语言,就看零基础C语言自学教程!绝对高效可靠。我们的C语言教程旨在打造一个有深度、有头有尾、系统性、公开免费的C语言教程。同时,也欢迎大家来提出批评指正意见。
关于专栏介绍,可以参看这篇文章呀零基础C语言自学教程正式开更!! - 知乎 (zhihu.com)
Part 1 前言


各位好呀~~这是我们的第一节内容,也是我们C语言的伊始。

本节内容,我们主要是简单了解一下C语言的全部知识逻辑,就是对所有的知识点有个大概的、总体的印象。可以不用追求细节。因为所有的细节,我们会在后面的文章中一一为大家详细阐述~~~
看完本文,大家能够达到的水平就是能够看得懂别人所写的简单的C语言代码啦~~~并不要求能够自己写出完整漂亮的代码。
(大家如果一次性看不完,可不可以到文章的末尾点一个【赞】,也是给村长的一个鼓励捏,【收藏】一下文章,防止之后的推文刷上去后找不到啦~~~)

也就是说,这些知识我们后面还会再说一遍,本文的定位是为后面知识的进一步讲解做铺垫用的。不过到那个时候,我们所站的高度不一样,讲解的深度也是不一样的呦~~~
不过本文毕竟涵盖了不少内容,内容可能有些长,还请大家耐着性子看呦,看完之后,可以说,你的C语言学习入门啦!!!
确实由于文章比较长,考虑到大家的感受,我们将其分为(上)(下)两个部分来介绍~但即便这样,还是好长hhh

本文是万字长文,看完需要一定的耐力(当然你也可以分几次看)和恒心,也是检验你是否能够学习下去的标准(如果这都坚持不了,趁早回家种田hhhh,因为做事情要有恒心才能做成呀~~~凡事怕坚持)
【若要看原文,请移步微信公众号【自学编程村】,那里的排版可能比这好看些零基础C语言自学教程(1)——初步认识C语言的全部知识框架结构(上) (qq.com)】

当然,你要是真的看不完,可以拉到文章最后,帮忙点个赞,或者在看,也算手有余香啦hhh~~~
当然啦,也可以先收藏再看。

好,我们现在正式开始。

Part 2 C语言简要介绍

我们先来扫一下盲。
宏观地介绍一下C语言的地位、什么是C语言,然后简单介绍下C语言发展史。

首先,祝贺你非常有眼光,选择C语言。
从语言的流传度来说,C语言、C++和JAVA在每年语言使用在1000多种计算机语言中稳居前三(最近Go的热度也上来了)。而C又是一门底层语言,却兼具高级语言和底层语言的特性,执行效率高,而且应用广泛,并且我们平时所用的两大操作系统--Windows和Linux 都是用C写成的。

关于它的发展史,简单说一下,C语言的祖先是BCPL语言。而在1970年美国贝尔实验室的 Ken Thompson。以BCPL语言为基础,设计出很简单且很接近硬件的B语言。然后在1972年,科学家们在B语言的基础上最终设计出了一种新的语言,取BCPL的第二个字母作为这种语言的名字,这就是C语言。来历还挺有趣。
每年,因闻C的大名而慕名前来学习的人数不胜数。可是,想要将其学好,还是需要下一定的功夫的。

而在C学好之后,我们可以学C++或者Java就易如反掌了。同时,你也因掌握了一门编程语言,在未来学习数据结构和算法、数据库、Linux操作系统等知识时理解的也就更加快速。

而如果你以后是做嵌入式开发的,是自动化、控制出身,那么学习C语言更是没得商量的了。
可见C语言的地位之重。
而网上也确实有许许多多的C语言的教程。但大多数教程都说的比较浅显,或者是豹头蛇尾,又或者没有系统的章法结构比较混乱,又或者是需要付费(而且质量还不能够保证)(但也不是完全没有哈~)
总而言之,找到一个比较好点的教程、系统性的教程太难了。
于是乎,我们的C语言教程努力克服这些弊症,打造一个有深度、有头有尾、系统性、公开免费的C语言教程。同时,也欢迎大家来提出批评指正意见。

Part 3 知识体系讲解

ok,我们现在就要开始介绍我们的知识点了。

我们先来看下本节的知识体系结构(思维导图)



(图1.1)

【再次声明下本文的定位:是简单的、初步的帮助你认识这些知识和知识体系,把你领入C语言的大堂】。而这些知识也足够你看懂简单的基本的C语言代码了。
但是需要知道的是,这里面有着许许多多的细节,我们不可能用一篇文章全部讲述完。所以我们是将其放在后面来去讲解。
【也就是说,这些所有的知识,我们后面都是要重新再来说一遍的!!!】
那个时候讲解,我们所站的高度不一样,然后讲解的深度也是不一样的。
【从另一个角度来说,本节内容,是为后面所有的内容做铺垫】
我们现在来介绍这些内容。

01 基本程序框架-hello world

程序员的第一个程序好像大多数都是从hello world开始的哈哈哈。

我们先来上代码,然后再来解释。
代码:(ps:我们所有的代码示例,都建议读者能够自己手动打一打,为了鼓励不要进行简单的复制粘贴,所以前期我们可能放的是截图)



(图1.2)

这段代码,可以说就是我们的hello-world程序的框架了。

将所写的代码运行起来,运行的结果可以看一下:(在VS中 运行 的快捷方式是ctrl + F5)
(附:VS的下载方法:C/C++环境配置(VS的安装及使用))
(如果你想要用VScode,VScode的下载配置方法:C/C++环境配置(手把手、负责任教你VScode的删除、安装及使用))



(图1.3)

OK,那么现在你可能会疑惑,那这段代码什么意思呢?
我们来解释一下:

对于这样一段代码,首先它有着这样一个框架:
我们要牢记:main函数是程序的入口,程序都是从main函数开始执行。




(图1.4)

然后具体到我们上面的有hello world代码,解释如下:
#include<stdio.h>   //意为:包含头文件,即包含stdio.h这样一个头文件。stdio.h可以理解为standard
                     //input output,即包含标准输入输出的头文件。.h后缀即为头文件的意思。

int main()          //程序运行的入口,也叫主函数,故称main,int表示整个函数返回值的类型,按照C语言标准委员会的规定是int
                    //这也恰好与下面的return 0相呼应(就是说整个函数返回了一个0,而0就是int类型)
                    
{                   //一个大(花)括号即包含一个代码段,在这里可以理解为是main函数里面的代码段。

  printf("hello world");//printf即意为打印,即打印printf里面的内容,注意,在这里,printf本质
                        //上是一个函数,一个库函数,我们称其为标准输出函数(standard output函数)
                        //被包含在stdio.h的头文件中。
                        
  return 0;         //返回一个整形(整数,下面会说到),与main前面的int相呼应,作为一个函数的返回值
                    //意为我整个函数返回了一个0,0是整型(即int型),所以就和刚刚在main函数前面的int对上了。
}那么现在,你也能写出来一个hello world的代码吗?试试看呢?


02 数据类型

数据类型是固定大小内存的别名
那常见的数据类型有哪些呢?
char字符型
int整形
long (int)长整型
long long (int)更长的整形
short (int)短整型
float单精度浮点型
double双精度浮点型
(表1.1)
这个表格不需要记。先有个印象。
我们来讲解一下:
1、通俗意义上,整型就是整数,浮点型就是小数
2、字符型为键盘上能敲出的任意一个单个字符。
那这些类型是怎么创建,怎么用呢?
(再次建议初学者讲笔者所有的代码在自己的编译器上自行操作一遍。实操很重要!)

数据的创建



像这样,我们分别将上述每一个类型都创建了一下,并且将其初始化了。所以,像上述的创建方式,可以总结为:    数据类型名+ 自定义变量名,这就叫数据类型的定义。在定义的时候给它赋了一个值(这里的10.2f仍然是一个数,我们下面会讲)意为给它初始化了一下。



(图1.5)

需要注意的是,不管是这里的变量名,还是我们后面所要说到的函数名等等,都只能够包含字母、数字和下划线这三种符号,并且数字不可以为第一个符号。(即不可以有int 0a = 10这样的命名存在)

那么就是说,我现在有这样一行代码:
  int a = 10;则它的含义就是,我定义了一个变量,它的变量名是a,它的类型是整型(整数),它的值是10。

数据的输入输出

我们现在来讲解下数据的输入和输出。
1、【含义】

先来理解下输入和输出是什么意思?
我们以整个程序来作为视角,程序里面有着运行的数据。可以认为,程序就是个黑匣子,然后在里面在做自己的事情。那么黑匣子在运行的过程当中,肯定和外部有数据的交换,即表现为程序和硬盘资源的数据交换(硬盘资源简单来说就是磁盘上的文件、还有键盘、显示器等外设)。这个时候,就需要用到数据的输入输出的操作来完成这样一种数据的交换。
输入即为input,输出即为output,所以数据的输入输出我们有的时候也简称IO。

这是广义的输入和输出。




(图1.6)

我们现在输入刚刚起步的学习阶段,所以我们就学习两个最简单的输入输出,叫做【标准输入】【标准输出】分别用scanf和printf来完成
这里的【标准输入】【标准输出】可以理解得再通俗一点,就是从【键盘里面输入】,【输出到显示器控制台上】。
就是说,scanf是用来接收我从键盘里面输入的数据的,而printf是用来将我想要输出的数据输出到控制台显示器上的。


2、【功能实现】+【代码释义】
那具体怎么样来实现这样的函数功能呢?
我们结合着上面刚刚讲过的数据的创建,来举一个例子进行说明:

来看这样一段代码:



(图1.7)

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main() {
    int a = 0;
    char b = 'a';
    scanf("%d", &a);
    scanf("%c", &b);

    printf("%d\n", a);
    printf("%c\n", b);
    return 0;
}我们来解释一下这个代码的含义。
(1)首先是最上面的一行代码(第1行)
与我们本身的程序无关,就是这一行:
#define _CRT_SECURE_NO_WARNINGS 1这个是由于我们这个环境的原因,我们必须要加上,否则VS的编译环境就会报警说scanf不安全(就像下面这样)(这个情况只有在VS中有。如果你是在其他环境,应该是不需要的)



(图1.8)

总而言之,一句话:在VS中用scanf,要加上那一句话。
但是难道我每次写文件如果要用到scanf都要加吗?那不是好麻烦?具体的操作方法可以看这篇文章:
好,这算是一个题外话了哈~
我们接下来逐行介绍一下下面的代码都是什么意思。
#include<stdio.h> //包含standard input output(标准输入输出)的头文件(2)第二行,意为包含(include的中文释义)stdio.h这样一个第三方库文件。它里面含有scanf和printf具体的实现方法。

由于我们的下面所要用到的 输出输出函数(即scanf和printf函数)不是C语言语法本身的内容,是第三方标准库里面的内容,我们必须要把这个<stdio.h>这样一个标准库引用过来,才可以去使用我们的scanf和printf。
(3)接下来,进入main函数(第三行)(请再次牢记,程序从main函数开始执行,从main函数开始,一行一行往下执行)。

(4)然后下面两行(第4,5行),我们定义了两个变量a,b;他们的类型分别是int(整型,即整数) 和char(字符型),然后,我们分别给它们赋上了一个初始值10和字符 'a'。
而这一个过程,正是我们前面所提到的变量的创建,同时给它初始化

下面是我们要着重说的输入(scanf)和输出(printf):

(5)接下来第6、7行,均意为输入。
一个一个说,先说第6行,它的意思是:以%d的格式,输入到变量a的地址处。再解释一下这句话,%d的格式是什么意思?%d可以理解为以整型的方式输入;这是一种格式化输入的方式。即告诉编译器,我下面要输入的这一个数是一个整型。
同理,%c是以字符的方式输入,%f是以float的方式输入。

那么我们是输入到哪里呢?输入到变量a的地址处
地址是什么?我们现在简单来理解,地址就是一把钥匙,能够拿到变量a的值的钥匙。&就表示取地址的含义,&a就表示取a的地址。所以,scanf后面的&a就意为着输入到a的地址处。可以理解为,我先用这把钥匙拿到了a变量的值,然后通过scanf输入到变量a里面。
请牢记:输入的时候,后面必须要跟上变量的地址。如果像下面这样写,是错的:
scanf("%d",a);除非变量a本身是个地址。(这点我们以后会说)

也就是说,不管怎样,我们在scanf的后面都要跟上输入目标变量的地址的。

即它的格式为:我先告诉编译器我要输入的类型,然后再告诉它我要输入到哪个变量里面去。

那么第六行的含义就是:我输入一个整型,到后面的变量a里。
同理,第七行的含义就是:我输入一个字符型(char)类型,到后面的变量b里。
那么现在有一个问题,就是我怎么知道%d表示的是整型,%c表示的是字符型,需要记忆吗?

其实用多了自然也就明白了。

具体看下面的表格。
附:部分%后面跟着不同字母的不同含义:(如果读者对部分不理解可以先放一放)
%c输入输出字符型(char)_
%d输入输出整型(int)
%f输入输出单精度浮点型(float)
%lf输入输出双精度浮点型(double)
%p用于输出地址(用于printf)
%s输入输出字符串
%u以无符号的十进制输出整型
%x以十六进制形式输出整型
%o以八进制形式输出整型
(表1.2)

那么如果我输入了值,原来在a,b里面的值怎么办呢?

答:原来的值被覆盖。即新的值取代了原来旧的值。
(6)继续说下面的代码(第9,10行),下面的代码就是用printf进行输出,也叫向控制台打印(就是运行起来后的弹出来的那个小黑框框就叫控制台)
printf的使用方法和scanf很像,也是在前面告诉完编译器要打的类型后,还要再在后面写入要打印的变量名字(就是说要打印谁的值)

所以第九行:即意为以%d(整型)的格式打印变量a。
第十行:以%c(字符型)的格式打印变量b。

而%d和%c后面的\n是换行的意思,意为我后面的输出将会另起一行(如果没看明白可以自己试一试,看看加上去和去掉运行时有什么区别)
--->我们将上述程序来运行一下看看:

在VS中,按住ctrl + F5或者ctrl + Fn + F5运行:



(图1.9)

如上图,假如说我输出3c,那么第一个scanf会读取到第一个3,第二个scanf会读取到一个c。分别存放在变量a和变量b中。
->  plus1 : 我们在输入的时候,还会发现一个有意思的事情。

我如果这样输入:




(图1.10)

这是什么原因呢?
实际上,我在输入一个3之后,我输入了一个空格。而我们说过,键盘上任何一个能敲出来的键都可以事一个字符。所以空格也是一个字符。
因此第一个scanf读入了一个3,把它放到了变量a中;第二个scanf读入了一个空格,把它放在了变量b中。
而且你看,它在输出的时候,实际上第一行输出了一个3,然后第二行又输出了一个空格。只不过你没有看见而已。那最后的那个字母c怎么办?答:看后续有没有人再来接收了,像这段代码没有人来接收,直接丢弃。

->plus 2 : 那再来思考一个问题,难道每一次空格都可以被接受吗?
如果我的代码长这个样子,我应该怎么输入呢?(注意看我的scanf里面两个都是 %d 了)




(图1.11)

像这样需要连续输入两个整型,必须要以空格作为间隔。
举个例子,如果你本来想要输入一个5到a里面,输入一个3到b里面,你中间不加空格,就会被识别为输入53到a里面(如果不明白自己动手试试)。



(图1.12)

关于输入输出,我们暂时先说到这里,因为它比较重要,所以我们花费的时间比较多。
我们还会在后续的不断练习中反复去理解、体会。

数据类型的大小

实际上,我们上面的每一种数据类型都是有大小的。

在此之前,我们先来铺垫一个常识:
计算机存储数据示意二进制的形式存储,每一个0或者1占据一个比特位。
一个字节=8个比特位;
一个kb=1024个字节;
一个MB=1024个kb;
一个GB=1024个MB;
一个TB=1024个GB;.......
一个机器,要么是32位,要么是64位;32位的含义就表明该机器使用32根地址线,每一个地址线可以通过通电或者断电来表示0或者1,表示一个比特位。那么就是说,32位的机器就有32个零幺(0,1)序列。这32个零幺序列的取值范围为从32个比特位全是0(我们称之为全零)到32个比特位全是1(我们称之为全幺)。范围是0 - 2^32-1。它的单位是字节(因为字节是计算机地址处理的最小单位)。把它除以1024(单位变成了kb),再除以1024(单位变成了MB),再除以1024(单位变成了GB)。可以用计算器算一下,最后的结果大约是三个G。

64位同理,是用64根地址线。
你注意看这里,这里x64就是64为平台,而x86就是32位平台(不是x32呦)




(图1.13)

好,铺垫完毕。
那我们来思考一下,每一种数据类型的大小是多少呢?
我们用一个C语言中的关键字:sizeof  来实现这个功能。
其中sizeof的含义是求某个数据类型所占空间的大小,单位是字节。比如,sizeof(int)就是指 int 的数据所占的内存大小。
当然了,sizeof也可以去求字符串所占用的空间的大小。这个我们以后再说,暂时先用不到。

我们来看下面一段代码:



(图1.14)

如图,我们可以看到,char类型的大小是1个字节;short类型的是2个字节;int 类型的是占4个字节;float也是4个字节....(注:long在有的编译环境下不是4个字节,而是8个字节。就是说,有的变量在不同环境里的大小不一样,比如在x64和x86环境里面有的变量大小就不一样
好,关于数据类型就先给大家介绍到这里,大家只要会创建、会打印,知道它们占据空间的大小就行。

03 常量和变量

变量

什么叫变量?

变量,顾名思义就是可以改变的量。
像我们上面图1.4里所说的创建的变量,即a,b,c,d,e,ch,它们都称之为变量。

因为它们所表示的值都可以改变。比如,我可以让a的值加1,也可以让b的值减1,让c 的值变成 50等等。这个并不难理解。

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

变量分为:【局部变量】和【全局变量】。


1、【局部变量】

定义于局部的变量。
这里的局部指的是在函数的内部中声明的。例如:



(图1.15)

上图中, 这里的a定义于main函数的内部,可以认为,它是一个局部变量。
同样的道理,在由上图中,我们的add是一个函数(函数具体的细节我们后面讨论,现在知道它是一个函数)中的x和y也都是局部变量。



2、【全局变量】

定义与整个程序的变量。
例如:(如下图)



(图1.16)

这里的c就是全局变量。在全局范围内定义的变量。
局部变量和全局变量类似于整体和局部的关系。
当局部变量和全局变量的名称冲突时,局部优先。(相当于局部又重新定义了一次)
例如:



(图1.17)

看,打印出来的就是20。
因为在printf这个地方,局部的a是优先于全局的。

变量的作用域和生命周期

1、对于全局变量来说,变量的作用域为整个文件,生命周期与程序的执行周期相同。

2、对于局部变量来说,其作用域为其所在的整个函数,生命周期为其所定义之时起,至函数运行结束后终止。(函数运行结束后,该变量所会被销毁,所占用的空间会还给内存)

我们通俗的说一下,全局变量在整个项目运行的过程中一直存在,并且一直可以用。但是局部变量在出了所定义的它的函数之后便销毁,便不再存在。


变量的使用

关于变量的使用,我们这里再提一些输入输出的一些内容。

我们来完成这样一个任务:
输入两个数(整型),并打印这两个数。
具体怎么样去做的,我们上面在【变量的输入输出】部分已经详细讲过,我们就不再赘述哈~

常量

常量,是指在给出值以后,不可以再被修改的量。(注意:这里我们所说的值是一个广泛的概念)


常量的类型

在目前的阶段,我们接触到的常量有如下四种类型。
1、直接定义的数值常量。
2、const 修饰的常变量。
3、#define定义的常量。
4、枚举类型常量。
我们接下来举几个栗子:
第一种:【直接定义的数值常量】。



(图1.18)

像这样,10表示一个数值常量;而字符‘a'表示一个字符常量。它们都是我们直接定义的数值常量。

第二种:【const 修饰的常变量】。
来看:



(图1.19)

像这样,前面由const修饰的变量a,就变成了常(变)量。常变量保留的变量的某些特征,但是它具有的常量的性质,其值不可以被修改
在普通情况下,我们均将其当作一个常量。比如,我让a+1,然后重新复制给a,这个时候,编译器就会报错:(如下图所示)



(图1.20)

第三种:#difine定义的常量:(就是我们所说的宏常量)
例如:(如下图)



(图1.21)

在这里,MAX就是一个常量,它的值为10。如果打印出来,可以看到,控制台上显示的为10:(如下图)



(图1.22)

同样的道理,如果将其值修改,我们会看到编译器会报错。
第四种:枚举类型常量。
对于枚举类型,我们要用到一个关键字enum,即通过enum来将常量一一列举出来。来举一个栗子



(图1.23)

从上面我们可以看出,我们在枚举类型中给出所要给的量的名称(我们这里列举的是男,女,保密,当然,你想列举什么就列举什么),那么它们就将成为常量;
(它们的值默认从0开始,以此往下递增。(提一嘴,因为它们代表的值是整形,所以我们可以用%d来去打印))   

04 数组     

数组就是把类型相同的元素放在一起,形成一个的集合。
数组的声明

数组的声明方式是这样的:


例如,我们可以这样声明一个数组:(如下图)



(图1.24)

1、这里的int的意思是数组中元素的类型全部都是int;
2、array是数组名,你想起什么都可以
3、[9]表示数组中有9个元素
4、{1,2.....,9 }表示数组的元素(你想给什么都可以,但前提是元素都要是你前面所声明的类型)
数组的初始化

像我们上面那样,在声明的时候,给它的元素全部列举了出来,就是数组初始化的一种形式。
这种把数组的元素一一列举出来的初始化方式,称为数组的完全初始化
另外一种数组初始化的方式,称为不完全初始化
比如:



(图1.25)

这表示什么呢?
表示数组的第一个元素为1,剩下的8个元素都是0。

数组的访问

那我怎么样才可以拿到(访问)数组的某个元素呢?
我们以上面的   int array[9]={1,2,3,4,5,6,7,8,9};   为例:
首先,数组的每一个元素都是有下标的。而且是从零开始,然后直至最后一个元素,依次递增。如图:



(图1.26)

那么,我们在访问的时候,是以数组元素下标的形式来访问的。
比如,我想访问数字2,那么我就可以用array[1]来访问。
那现在,我们把它打印出来:



(图1.27)

其它的元素访问规则以此类推即可。
注意:在这里要强调一下,数组中的元素类型一定要相同。

05 字符串     

字符串,字面意思,就是指字符和字符在一起形成一个串。
字符串一般会用双引号引起来,而不是单引号。
比如   “abcde”   就是一组字符串。
在C语言中,没有单独的专门用来声明字符串的类型。所以我们把它放在字符数组中去声明。举个栗子:(如下图)



(图1.28)

这便是一个字符串。
我们来分析一下:



(图1.29)

我们可以把字符串理解为一个特殊的数组,或者就是一种字符数组。
注意:

在每个字符串的后面,其实还隐藏这一个'\0'。它不算到字符串的长度中,但是却占据一个单位的空间。它作为字符串结束的标志,匿藏在字符串的最后。
比如,上文提到的字符串"abcdef",它的字符串长度是多少呢?(如下图)



(图1.30)

也就是说,这个字符串长度为6。
我们可以来验证一下。
验证时,需要引入一个库函数:strlen它用来计算字符串的长度。计算的原理是从字符串的第一个字符开始,一个一个向后遍历,直至遇到'\0'为止,计算'\0'前面的字符个数。用它需要引头文件<string.h>
(解释一下:前面的array[9]表示改数组的最大容量是9,而这个字符串的长度是6,加上\0,一个占用了7个空间。也就是说,在9个空间里,实际使用的只有7个,而strlen是不会将\0计算在长度内的,但是sizeof会。放在总空间为9的数组中。原数组的元素实际上是a b c d e f \0 x  x)(x表示随机值,但一般也为\0)
看下面的栗子:



(图1.31)

可以看出,该字符串的长度为6。而字符'\0'是不计入字符串长度中去的。

06 转义字符     

【案例分析】
我们输入这样一行代码:



(图1.32)

我们让代码运行,来看一看会输出个什么样的东西


一堆乱码?其实不是。
那为什么会输出这么个鬼东西?这就与转义字符有关系了。
在这里我们先提一下ASCII码,它的全称为美国信息交换标准码。它实际上是一个字符-数字转换表即我们在计算机中,给定一个数字,它在内存中其实还对应着一个字符。同样的道理,我们在计算机中输入一个字符,它在内存中其实还对应着一个数字。而其所遵循的转换的规则就是ASCII码表(注意:该数字是有范围的)。现我们把ASCII码表给出:



(图1.34)

简单来说,就是一个字符,比如字符'a',它实际上,在计算机内存储的时候,存储的是97。也就是说,我们所有的字符,在计算机中都是以它的ASCII码来存储到计算机中的。
那如果是数97呢?那该怎么存储就怎么存储呗。按97存储呗。
那就是说,97既可以表示97,又可以表示字符'a'?   答:是的。
举个例子来看下:



(图1.35)

如图,我将同样一个数字(97),我先让其以整型的方式输出(%d)的方式,得到的结果是一个97;再让其以字符型的方式输出(%c),得到的结果是字符'a',所以就是说,字符'a'的值在计算机内存储的时候就是97。

ASCII码我们介绍到这里。那么回到刚刚那个例子,编译器在遇到’\t‘后将其转义,不再是原本含义,而是转变为水平制表符,相当于一个tab键缩进的长度,大概相当于4个空格(多少个空格可以自己改)。
而\102也是一个转义字符。这里的102是八进制数字,它输出的为八进制数 102 在系统中所代表的ASCII码值。\102转换为十进制就是8^2+2=63,而在上面的表中我们可以看到它(63)所代表的字符为B。
\n也是一个转义字符,它的意思是换行,我们之前提到过的。
好,我们再回到转义字符的一般情况上来。
【转义字符表】



(图1.36)

这就是相关的字符相关的转移。
上面的表格中,\ddd中的每个d表示一个八进制的数,\xhh中后面的每一个h表示一个十六进制的数。
当编译器遇到\a时,电脑会响一下,\b表示退格,\f表示换页,\n表示换行;\t表示水平制表符(相当于一个tab)......
那么,我们就可以解释一下刚刚为什么打印出来那么一堆乱七八糟的东西了




(图1.37)

其中,转义字符算一个字符。

【案例再分析】
那好,我们看一下下面的这一串字符的字符长度是多少:
\1133\138\test\\.c\n



(图1.38)

看看你有没有算对。

为什么是12?
根据我们上面说的,



(图1.39)

数一数,刚刚好12。那个\138后面有个数字8,所以就不能用来表示八进制了。
实际上,转义字符的颜色和普通的都不一样了。
好,转义字符我们就说到这。

07 代码注释     

先行的代码有两种注释方式。
第一种,是C风格的注释方式:用/*   */;
第二种,是C++风格的注释方式,C99后流行,用  \\;(如下图)



(图1.40)

当然,/*   */这种注释方式是有一定的缺点的:即不可以嵌套。请看:(下图)



(图1.41)

我们先把main函数里面的注释掉,再想在外面注释的时候,我们发现,后面的括号并没有被注释掉。

08 函数     

函数是C中最重要的一个部分。
可以说,一个程序是由若干个函数组成的。那么函数到底是什么?它到底怎么用?我们今天在这里先稍微地提一下,读者只需清楚什么是函数就好,我们今天只是简单的介绍一下,不深入,不发散。
首先,函数有两种,一种是库函数,一种是自定义函数。

【库函数】

我们用的printf;scanf;strlen都是库函数,也叫内置函数。包括我们常常提到的main也是一个函数。可以这么理解,库函数是别人为你写好的,然后打包封装到像<stdio.h>这样的头文件中去。你用#include表示包含这个头文件,那么你就可以去用这个头文件中定义的所有函数。

【自定义函数】

我们再来讲讲自定义函数:

我们想要用一个函数,只需要把函数的名字写出来,然后打上括号,把函数的名字写进去就行。就像这样ADD(a,b)。我们将在下面的实例中给大家演示:

1、【函数的调用】
现在,我们来写一个最简单的函数——相加函数,就是把两个函数加起来。
我们先把主函数(main)写出来:(下面的代码是main函数里面的内容)



(图1.42)

ADD(a,b)就是函数调用的意思。也就是说,我要调用这个函数,经过什么过程和操作我暂时不关心,但结果是通过这个函数,我把我传进去的a,b两个数加了起来,得到了它们两个数的和。然后我用sum来接受这个ADD函数返回来的和。(也就是这个值)
上述所描述的就是函数的调用。再说的直白一点,就是用了函数的方法。

2、【函数的实现(定义)】
那么有了调用,我们就需要来去实现这样一个函数。
那么,我们现在再来看看如何实现这个函数:(也就是得到这个值所经历的过程是什么)
函数实现的基本架构是这个样子的:



(图1.43)

我们仍然以上面的函数为例:
上面的函数我们可以写成:



(图1.44)

这样,我们就实现了这个函数。
我们先来讲讲这每一部分都代表这什么:



(图1.45)

好,我们再在整体的代码中来看一遍,将代码怎么执行的说一遍(此图是我之前耐着性子画的)。



(图1.46)

所以,打印出来的值应当为30。
需要说明一下的是,我们最好把要用的函数写在main函数的上面。因为如果写在main函数下面,编译器在调用这个函数之前并没有见过这个函数,这样就会报错或者报警告。除非在前面进行一下声明。就像这样:



(图1.47)

也是可以的。像上面那样,只写了个函数的返回值、函数名和函数的若干个参数、然后后面再打上一个分号的形式,我们叫做【函数的声明】
有了函数的声明,我们就可以在任意位置去进行函数的定义(也就是函数实现),否则的话,就只能在调用该函数的 那个函数(比如这里调用ADD函数 的函数时main函数)的上面去定义它。
好,就此打住,函数我们今天就了解到这。读者只需要了解函数是什么,怎么创建的就可以。

好啦,我们《初步认识C语言的全部知识框架结构(上)》的内容就暂时介绍到这里。

我们回顾一下我们都说了啥?

1、我们首先引入了C语言是什么。
2、然后紧接着,介绍了C语言的基本框架。
3、并依次介绍了数据类型。
4、常量和变量。
5、数组。
6、字符串。
7、转义字符。
8、代码注释的两种方式。
9、函数。
你看看自己都能想起来说过的哪些内容呢?

下节内容,我们也就是《初步认识C语言的全部知识框架结构(下)》,我们将会把剩下的内容介绍完毕,它们分别是控制语句(分支语句)、循环语句、各种操作符、关键字、还有指针、自定义类型。

如果觉得文章比较好,那就点个小小的赞或者再看吧~~
要是怕找不到,也可以进行标星或者收藏呦~~~
没有关注的朋友也可以来点个关注呦~~~~


自学编程村】专注于自学编程领域。由USTC、WHU、SDU等高校学生、ACM竞赛选手、CSDN万粉博主、双非上岸BAT学长原创。分享业内资讯、硬核原创资源、职业规划等,和大家一起努力、成长。
欢迎加入自学编程村。下节内容,敬请期待~~~
回复

举报

3

主题

12

帖子

20

积分

新手上路

Rank: 1

积分
20
发表于 2025-3-26 08:02:27 | 显示全部楼层
为了三千积分!
回复

举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表