C语言入门基础必备知识串讲-详细梳理!(新人疑惑解决,建议收藏)

Posted 码码咪呀

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言入门基础必备知识串讲-详细梳理!(新人疑惑解决,建议收藏)相关的知识,希望对你有一定的参考价值。

本文对C语言基础入门知识进行了粗略的讲解,带你了解一下基本的大纲,画出导图系统论述写出的过程令我受益颇多,为了不浪费大家时间你可以预先选择一个你感兴趣的目录查看下讲解是否正确以及能否有那么一点的启示,然后再看看其他内容的讲解,写到的地方都超乎的详细,愿能给你带来一丝明悟,若有错误之处欢迎提出指正

这篇文章绝大大部分知识都涉及了 进制内存方面的知识 在这里一言两语数不清,因此重新写了一篇专门进行讲解   点击 内存、进制模块详讲 跳转观看

printf("感谢观看!\\n");

目录

一、变量

1.常见数据类型

2.变量定义及其分类

2.1 变量作用域、生命周期

二、字符串及数组

1.数组

1.1 数组定义

1.2数组使用:

2. 字符串

2.1 部分转义字符

2.2 初识操作符

三、常见关键字

1.typedef

2.static(extern)

3.register

四、常量

1.const 定义常变量

2.#define 定义常量

3.enum 枚举常量

五、选择、循环语句

1.选择语句

2.循环语句

六、函数基本知识(两个例子说明)

1. 加法函数

2. 取最大值函数

七、 指针

内存相关

指针定义详解

八、 结构体

九、操作快捷键及其注意事项


文章思维导图


一、变量


1.常见数据类型

相信小伙伴在入门编程的时候一来就会遇见该类语言数据类型的学习,不知道你们有没有想过其中的缘由?在计算机编程语言学习过程中,无论选择哪一门语言都首先要学习该语言规定的数据类型,它构成了整个计算机的大厦。计算机最擅长的就是计算,一切大大小小的问题根本上最后都是由计算解决的,而计算需要有数值,有地方计算,类比生活中 整数,小数,计算机里面也规定了字符型,整形等,至于为什么规定数据类型就像你问生活中为什么需要整数,小数一样,计算机的根本就是计算,我们日常遇见的关于计算的小问题不外如是,即使知道你也不会刻意去定义数据类型的概念,同理生活中的一切由计算机完成的工作也是由大大小小的计算实现,故而不同于人类,要想计算机准确无误的按照要求为我们服务,它的每一个定义都需要有严格的标准,数据类型的定义与应用必不可少,它好比从小就开始学的1、2、3一样,价格我们常用小数、年龄我们用正整数,这些细化都是为了给贴合实际的解决问题,入门的知识必定是以后学习最重要的构成部分...

对应于生活中的列数式计算,数据类型规定了数值类型计算的地方和数值的类型,而需要运算的数值也就是我们接下来会提到的变量 ,它往往就是我们解决实际问题所需要运算的值,它们被存放在 各种数据类型定义的空间里,而计算机的空间不可能无限制的给下去,因此每种类型都对应有一定的大小,点击 内存、进制模块详讲 跳转观看 深入了解计算机变量内存的分配原理,并且在运算完之后就会回收相应的空间,下文提到的变量可行域和生命周期。这里我们通过sizeof()操作符求它们各自规定的大小

相信很多人在初学的时候都有这样的疑惑,这里求得的大小是什么大小,虽然知道是内存大小但是知道的也不具体,由以下图知(至于更大的单位倍率都是*1024)

而这里sizeof()求得的是字节 byte 具体的请见后面 移位操作符

以及打印函数printf()里面为什么这样写

''%d\\n''  是什么意思?  其实这里%d 是一种操作符 意思是需要打印的内容类型是整数型数字 像这样的后面还会讲到其他几个常见的  而'\\n'是转义字符  意思是打印的时候换行,避免打印的时候都在同一行,紧凑 不易观察--涉及了下面内容 部分转义字符


2.变量定义及其分类

什么是变量?变量就是一个会改变的量,比如我们记录一个人每天的作息时间时,这个时间就是一个变量,计算机是严谨的,变量定义的时候多一秒少一秒,存放的地方(分配的内存地址)以及定义的地方(可行域)不同都是不一样的,不能想当然。因而有了全局变量局部变量的区别,而我们定义一个变量就是需要用到上面的数据类型,它类似菜市场的菜价,过一段时间可能就会有浮动,因此它是变化的,而我们要具体定义这个量就需要用到数值,即菜的价格,一般菜价都是小数这就是菜价的类型,而变量的定义也类似,这样写

后面的例子 可以尝试着分辨一下 定义的变量 学以致用

全局变量:定义在外面的变量

局部变量:定义在内部的变量

全局变量与局部变量的优先性:

当全局变量和局部变量同时对一个变量赋值时 以局部变量的赋值优先执行


2.1 变量作用域、生命周期

生命周期:一个变量总不能无限制的使用下去,不仅占用内存而且如果无关紧要的闲置着毫无用处,因而出现了生命周期的概念,我们知道 人的生命周期就是从出生到死亡,同理 变量的生命周期也是从创建到销毁。局部变量的生命周期就是 范围内只要使用完了 它就经历了创建到销毁 以便高效率的利用,而全局变量的生命周期对应于整个工程 意思就是只有工程销毁了全局变量的生命周期才算结束

作用域:作用域就是变量能够作用生效的范围,由上可知作用域及生命周期概念的提出无一不是为了提高运行效率及减少内存占用,故而都是按照需求定义变量的类型,只在一个地方用到的变量就无须建立成全局变量

看上图  可知 当我们在解决方案这里右键添加项目的时候 所创建的就是一个工程,在图中3.草稿就是一个工程。因此里面的 main.c/test.c 就都属于这个工程 即全局变量在两者之间都有效

我在 mian.c 里面也能使用该全局变量  不过需要 extern 进行引用,这里记住全局变量的引用需要这个函数就行,它就类似于我们使用 printf()函数的时候 需要在开头加一个 #include<stdio.h>库函数一样,用人家的总得给人家说一声 即 声明使用


二、字符串及数组

1.数组

1.1 数组定义

定义:数组就是一串相同类型数据的集合

那数组存在的意义是什么? 其实数组最直观的例子就是Excel,不难发现,生活中大大小小的统计都涉及到了数组,一个班级的人统计家庭住址这时你的信息就是一组数,注意:这里一组数是代指,并不只是数还能是其它类型,文本型,浮点型等,因此这里在此说明了开篇数据类型的重要性,数组也有数据类型,而类型也和变量的一样

下图是数组的定义

留意一下的是,数组的大小不能为0,既然得存放一些数据肯定不能是0,下面还有实时存储使用类的数组,类型不固定 看情况使用

我们刚才实现了将相同类型的一组数据的存储,那存储的意义是什么?不就是方便自己更好的查看吗,那如果我需要将里面的数据取出来那么多数据应该怎么取?瞎猜?这里就定义了数组的下标下标从左边开始到右边结束,下标从0开始,如图

1.2数组使用:

殊途同归 我们储存的数据总归是以后有用才会进行储存,因此数组的使用说到底就是相同类型数据储存和提取

下面我们以打印 1---10 为例进行数组内容的打印(涉及了后面选择、循环语句内容)可以跳到后面做个了解回来观看

正序打印数组内容 将内容按照下标序号依次打印出来

同理逆序打印


2. 字符串

定义:字符串是什么,就是一串字符的集合 字符就是单引号 ‘a’ ‘b’ ‘1’ ‘你’ 这样的都成为字符,类型是char,而字符串是由双引号括起来的字符的集合 "你好"     'hello world"。这里你可能对hello_world程序又会有了新的认识,我们从一开始到现在逐渐将这个入门程序剖析清楚。

常见的字符串的表示方法有如下3种:

1.直接定义字符串数组

2.printf()里面双引号内容也是

3.通过定义字符数组将所需内容打印出来

我们会发现上面第3种方法 出现了乱码。打印的东西根本不知道是什么,这里涉及到了下面转义字符的内容(其中 %s 指的是打印字符串,%c 打印字符 %d 打印整形数字 这些不用刻意去记 基本学习过程中慢慢就会熟练运用了)

下面我们来探讨一下为什么会乱码,以及明明我们只有三个字符却打印出那么些不知道的符号乱码

而这里字符又是什么?它是构成计算机符号的基本组成 比如我们平时用的abcdef 这些都是规定了固定的字符是多少 如下表列出了计算机字符 当我们想打印出一个字母时只需要找到对应的码值就行,这里ASCII码值表区分大小写的 ,例:

这里有心的留意到,ANCII码值对应的数字是10进制 而不是2进制 16进制其他的(10进制就是生活中见到的0-9构成的数),我们平时看到的数字都是10进制的  点击 内存、进制模块详讲 跳转观看深入了解进制相关的知识

这里比如我们打印字母A( A-Z 65-90 / a-z 97-122 )


2.1 部分转义字符

定义:转义字符是什么,字面上讲就是转变了原来想表达的意思 原本是一个字母或符号 但是加了一个' \\ ' 意义就发生改变,辅助程序直观输出的字符

直接看定义可能会有些蒙,光说不练假把式,也得不到提升,例:

注:我们很多时候不用运行程序就可以知道一个程序有没有错,有错误或哪里不符合规范的时候系统都会有提醒,不论是有错误的地方还是下面的错误列表和输出栏

回到刚才的错误:为什么这样打印不出来

原因是 " " , '  '都是两两互相配对的  系统默认将前两个配在了一起 故而后面的无法识别 导致报错

这时我们加一个' \\ ' ,将它原本的意义转变一下就不是原来那个  单引号双引号的含义了,就能继续打印

我们来看一个例子,看看它最后打印的数字是多少,就能解决上面乱码问题

一样的打印,为什么字符串能正常而字符不能正常呢?不用想都知道,它们中一定差了什么,

而这里 就涉及到了  '\\0'  终止字符 的使用,规定 在字符串的末尾都自带了这样一个终止字符,当程序识别到这个字符时就表示打印结束了,反之继续执行打印下去,故而 字符 数组里面并没有这个终止字符,因此程序打印的时候根本识别不出来只能随便在一个地方漫无目的的停止 造成乱码以及求得的长度是随机值

那怎么解决?还用问 加上一个'\\0' 它不就成了?

我们再来看一看:

细心的你发现了吗,这里的 '\\0'是不算做长度的

问题解决了!!!

一鼓作气,看看下面这个例子打印的值是多少?

注意,这里需要记得你数个数的时候,转义字符不要落了 视为一个字符

这里的输出是20 你数对了么  

需要留心一点的是 这里面的 \\t   \\168  其中 \\16  算一个字符 对应上面末尾  \\dd 表示1-3个八进制的数字 8已经不属于八进制的范畴了因而不算  (转义字符只能算作1 )

然后我们将它们打印出来,却发现格式并不对 ,不是我们想要打印的路径

这时我们就需要像前面一样 加上斜杠 \\  给它转义

这样就行了


2.2 初识操作符

1.算数操作符

下面来看个关于取余数和取模的例子:

这里简述一下 算数操作符 % / 的区别

eg:  21 ÷ 10  商 2 余 1

21 10 = 2  取的是 商

21 % 10 = 1 取的是 模(余数) 较常用

2.移位操作符(>> / <<)

这里值得指出的是,我们在计算机看到的数字大多都是 以10进制的 方式呈现的 至于进制的转换问题请务必抽空 点击 内存、进制模块详讲 跳转观看

移位操作符针对的是二进制的左右移动,详细原理如下所示:

3.位操作符

这里由于涉及太多关于二进制的知识,故此重新写了一篇关于进制之间基本知识及转换的博客,点击下方链接跳转观看,直接目录跳转就可以找到 位操作符 相关的内容

点击 内存、进制模块详讲 跳转

4.赋值操作符

如图所示使用方法

5.单目操作符

逻辑反操作( ! )

正负值(+ / -)

~(二进制按位取反)

这里不进行讲解 请到下方链接文章中查看

点击 内存、进制模块详讲 跳转

-- /++(前后置)

而对于后置的 

强制类型转换

当类型不一样的赋值时

我们在3.14前面加个括号(想转换的数据类型) 这样他就不会报错,但是确如它所说的,会导致数据丢失 于是打印只出来了个 3

6.关系操作符

7.逻辑操作符(&&、||)

注意 当表达式较复杂 容易混淆时 可以在表达式 及 操作符两边内容加上 括号 ()  阅读效果更不一样

相反

8.条件操作符

9.逗号表达式

10.下标引用操作符

下标引用

函数引用


三、常见关键字

关键字:就是C语言本身规定好的一些函数类似功能的字符,比如常用的return 数据类型等,同时也警示在定义变量时 变量名字不能够与关键字重名冲突

这关键字虽然看着比较多,随着慢慢学习练习,你会发现都不用记就都掌握了,这里就挑几个进行阐述,后期文章会有深层次的讲解

关键字及其基本分类

1.typedef

自定义关键字变量的名称(类型重命名)

2.static(extern)

上面在全局变量那里已经提到过了一次,全局变量使用的申明,评论里面也说过extern是C语言的关键字,其实全局变量部分的用法大致已经差不多了,大同小异

这里我们先来看两个例子 带入问题认识这两个函数  先想一下下面函数的输出 以及为什么是这样

在前面内容中我们有提到过 局部变量 全局变量生命周期的概念,可能那时候你就没怎么放心上,心想凭经验这种概念性的东西应该知道了解一下就行,话这样说没错,只是你并没将其了解透彻

生命周期还有些懵的可以回到前面变量部分再回顾一下

我们说 类似人的生命周期 出生-死亡  程序也是 创建-销毁 只是有随着工程销毁的 有随着代码块销毁的 这都取决于定义变量时 可行域 的大与小  

这里我们把可行域生命周期的概念带入就不难理解,上图中每次调用这个函数过后,到下一次调用的时候,上一次创建的变量a已经被销毁了,也就是说它的生命周期已经结束了,下次再次调用这个函数的时候又是一个的变量a它的值又会是1,又重新开始,所以这样无论调用多少次函数,输出的永远都是2

这样你能理解吗? 好,结合上面所说的 我们加入一个static 看看输出又会是多少

我们大致已经知道static的作用了,将生命周期变大,脱离了局部、全局 的束缚

那看到这里了,我们不妨继续想想之前变量的时候学习的东西,还讲了一个全局变量,里面有extern,是不是这个static也与extern有关联呢?

我们得到 全局变量一个性质:外部链接属性(前面变量部分涉及不合适故而没讲)

=> 同一工程 不同源文件之间 创建的全局变量 经过extern声明之后是能够进行调用的

那我们想 既然局部变量加了static后生命周期会变化那全局变量这个调用又会怎样呢 是会脱离工程的束缚?还是恰恰相反 被局限?

可以看到,加了static之后,反而不能调用了,这说明就是我们刚才想的恰恰相反的情况

这说明,全局变量的外部链接属性经过static 这样一加之后变成了内部链接属性,范围缩小在了本源文件之间了,而不是工程源文件里面通用

下面,介绍了全局变量,局部变量,提到调用,那还肯定有函数的调用

一看,发现大同小异的调用方式,都需要借助 extern 才能进行跨文件的调用,结论同上 函数也具有类似全局变量的外部链接属性

=> 同一工程 不同源文件之间 创建的函数 经过extern声明之后是能够进行调用的

那我们不妨想之前全局变量一样用static修饰看看效果

这说明同样,函数的外部链接属性 经过static这样一加之后变成了内部链接属性,范围缩小在了本源文件之间了,而不是工程源文件里面通用

这便是extern 和static 的常见问题

3.register

寄存器知识涉及内存 我打算把它放到下一篇文章--关于进制 方面知识进行细讲,相信对你会有帮助

点击 内存、进制模块详讲 跳转


四、常量

看到这,你可能会有疑问,为什么不紧接着变量的时候就把常量给讲了,而是中间穿插了数组和字符串的内容 其实只是为了加深你常量,含义的理解

定义:常量顾名思义就是不会变的量,在整个工程过程中都是一样的

我们上面详细讲了数组,你是否还记得 数组[ ]里面的内容要求 必须是什么?没错就是某一个固定的常量,当时说了看情况可加可不加,而一旦加上去就必须是常量 原图是这样的,那我们不就可以利用这个方法判断常量与否了?

1.const 定义常变量

=>  这里它提示报错了,本身a就被我定义成了变量,而这里const 将a属性改成了常量 (即不可修改)如图中1箭头,当给a赋值20的时候它提示不可修改因为const将a属性改成了常量,但又如图中2箭头,提示我们输入常量表达式,因此它并不能作为一个常量定义数组大小,所以它是一个不完整的常量还是个变量,只是具有了常量属性的变量,故称它为常变量

2.#define 定义常量

注意一下,这里#define并不是关键字 而是一个C语言内置的操作指令 这样记住就行

而同样的问题 #define 定义的就毫无问题

这里并未报错,说明#define 定义的值是常量,也从这里 知道了常量的不可修改性

多提一个知识点:#define 定义宏   类似于函数

3.enum 枚举常量

枚举常量,适当了解一下

枚举的量像数组一样从0开始数,它的值是数字 注意一下格式

而且我们看到将枚举的量放数组中并未报错,证明 枚举的值就是常量


五、选择、循环语句

程序的逻辑是由大大小小的语句串联起来,这些语句表示判断、循环、选择,就像粘合剂,它决定了程序什么时候执行什么代码,主观上讲,它就相当于代码的核心中枢,掌管着意识,支撑着程序有条不紊的运行

这里粗略提一下有个大概了解

1.选择语句

if()   else() 选择语句

举个例子 :如果你代码超过了20000行,你就能拿到份好offer,没有的话继续努力

这便是选择语句,无论选择哪一个都有不同的执行效果 注意它的格式

2.循环语句

while()循环 满足括号里面的条件就进行循环


六、函数基本知识(两个例子说明)

函数:当我们一个工程里面代码的数量很多时又需要不断地引用同一个代码块的功能时,如果每次都去定义重新写逻辑语句的话就会变得繁琐冗杂,而这时候我们只需要将它封装成一个函数就能在以后轻松地调用,极大地节省精力

1. 加法函数

写一个函数表达加法运算效果

2. 取最大值函数

写一个函数比较两个数的大小


七、 指针

内存相关

说到指针 我们就不得不谈到内存地址的相关知识,我将它具体的分作了几个部分的内容 从内存到进制 详细的描绘  相信通过这篇文章的了解 对你的关于C语言的学习大有裨益

点击 内存、进制模块详讲 跳转

指针定义详解

首先我们需要知道,什么是指针。我们知道,当定义一个变量时,该变量的地址是随机分配的,类比于人的身份证 它们都有一个编号 也就是地址 ,这样方便我们更好并且详尽无误的找到需要修改的值进行修。

有的人可能会说 既然我们都知道是 变量 int a 了 我们直接 改a不就行了么?换个层面上说 当一个程序较大时就像人类社会 个体上升到县市的级别 重名的人会非常的多 ,同理 程序里面变量也是会出现重名的情况,这样一来 无疑增大了使用难度,因此 使用独有的地址编号 往往更加准确便捷。或许这个例子充满悖论 论据不足 但指针地址的存在直接要害,从根本上找到问题所在是不容置疑的

综上所述:指针就是一个我们指向某个变量的箭头,而这个变量存储着某一变量对应的地址,这个变量即为指针变量,帮助我们更好且便捷的进行修改使用...

这里 我们将 a 的地址编号存储起来

pa 就被称作是一个存放地址的变量 因为地址具有指向性的作用 因此 pa 又称作 指针变量(注意 是变量就有类型)

注意其类型及其写法:

1. 指针变量pa 的类型和 a 的类型 一致  int  视情况而定 类型就是pa 所指向对象 a的数据类型

2. 在 数据类型 int 和 变量 pa 间 需要加上一个 * 号  规定写法 代表pa是一个指针变量

3. 指针变量 pa 的类型就是  int*  视情况而定 只是多了一个

解引用:

        需要想清楚的是,鼓捣出指针是干嘛用的,不可能为了加强学习难度故意弄个毫无实用意义的东西,根据存在即合理,指针的存在就是方便我们脱离可行域、生命周期等对一个变量进行准确的修改利用,而利用就是 *pa(解引用) 进行修改,下图展示了 变量、指针变量、解引用之间大体的关系:

通过以前的推敲 不难得出  变量 a 的地址就是指针 存放指针的变量 pa 就是指针变量 可以通过指针变量的解引用操作 *pa  对变量a进行准确的修改

我们通过解引用直接修改变量的值,注意其具体的写法

 


八、 结构体

结构体的产生

        什么是结构体?我们知道 C语言中类比于生活中解决问题需要规定了的各种类型的数据类型,但总有一些 实际问题中的类型无法加以描述。比如说 描述蔬菜的价格我们用浮点型即可、描述年龄用整形、但我要描述一个学生抽象的概念时,包含了其姓名、年龄、年龄、身高、学号、班级、联系方式等... 普通的数据类型就不能进行具体的表达,因此 struct结构体的出现就是为了解决这一类抽象概念的描述,并且它应该是根据各种信息进行的多种数据类型的整合,但它也是一种数据类型

       具体写法如下所示:

 我们可以看到,struct 是由许多实际信息对应的数据类型的整合,其本身也是一种数据类型,涉及数组表达的情况得视情况规定大小

       

        结构体的使用

1.  基本使用 用 变量名 s1(任意命名) 即 s1.(结构体中定义的名字进行表达)赋值就对应着结构体里面的顺序进行

 

2. 之前提到的 指针变量解引用 *pa 相当于就是变量 a 用指针进行表达(有些懵就回指针好好琢磨琢磨)

 3. 第2中表达方法中指针表示的简化  ->

这种用指针的方法无疑更加简单 以后的学习过程中也会经常使用 需要格外注意!!!


 

九、操作快捷键及其注意事项

常见的快捷键:

Ctrl K+Ctrl C  快捷注释

Ctrl K+Ctrl U 取消注释

F5运行

F10单步调试

注意事项:

注意事项在文中基本都有提到过

1.注意 看下软件中的 所写代码如果出现 红色波浪线和下边 输出 错误列表窗口 显示有错误 都是在你写代码的过程中实时的提醒你格式什么的有没有写错,符不符合规定书写规范的

2.当遇到 莫名其妙的问题时 静下来梳理遍头绪 然后看看自己到底是细节问题还是根本性问题 借用 F10单步调试 监视窗口随时观察,这是项很重要的能力

3.Ctrl S 是个好习惯  过一会儿保存是必要的 这不是软件会不会实时给你保存的问题,这是个人习惯

文中部分内容不易在本文涉及过深的 已经在其他文章中写出 点击下方链接 助力一键三连

点击C语言scanf()常见错误解决跳转

点击 内存、进制模块详讲 跳转


后面 语句、函数 讲的略微粗糙了 ,以后详细的讲讲

这篇文章已肝了很久了  到现在感觉已经精疲力尽的感觉,将所有的内容构建好系统的论述一遍蛮累但也蛮爽的,还有好些内容需要去补充,之后慢慢来

如有描述不清或根本性错误希望能帮我提出

以上是关于C语言入门基础必备知识串讲-详细梳理!(新人疑惑解决,建议收藏)的主要内容,如果未能解决你的问题,请参考以下文章

C语言入门基础必备知识串讲-详细梳理!(新人疑惑解决,建议收藏)

C语言入门基础必备知识串讲-超详细!(新人疑惑解决)

RHCE基础知识梳理

苍识——学科知识篇:C语言基础

Python3详细的数组基础操作-入门必备[列表的操作]

Linux基础知识点