赫斌C语言——笔记目录

c语言编程预备知识流程控制函数变量指针结构体位运算符

前段时间康哥看我C语言基础不牢,推荐我学习郝斌老师的C语言课程,花2周看完之后发现确实是目前所看的C语言课程中最好的,不仅非常适合入门,而且对即使学了几年C语言的也有帮助。因此我也非常建议小白或者感觉C语言基础不好的观看《郝斌C语言自学教程》。

下面是我观看视频所做的笔记,需要观看视频的同学可自行查看。希望对大家有所帮助,如果有大佬发现文章有错误的地方,希望评论区留言指正😀。

c语言编程预备知识

c语言编程预备知识

CPU 内存条 硬盘 显卡 主板 显示器 之间的关系

先将硬盘数据调用到内存,CPU处理完内存数据后将处理的数据发送到显卡,他们之间通过主板进行(各种任务的分配)运作和组织。 HelloWorld程序如何运行起来的

软件请求操作系统执行,操作系统调用CPU,CPU再将处理的结果返回给软件并在显示器中显示 什么是数据类型

基本数据类型

整数

整型 —— int(4字节)短整型 —— short int长整型 —— long int 浮点数

单精度浮点数 —— float(4字节)双精度浮点数 —— double 字符

char (1字节) 复合数据类型

结构体枚举共用体(快淘汰) 什么是变量

变量的本质是内存的一段存储空间 CPU 内存条 VC++6.0 操作系统之间的关系

变量为什么必须初始化

所谓初始化就是赋值若不初始化,内存中变量的原数据可能会影响程序 如何定义变量

数据类型 变量名 = 要赋的值 什么是进制

逢n进一:十进制是逢十进一、二进制是逢二进一 常量在C语言是如何表示的

整数

十进制: 传统写法16进制: 前面加0x或者0X八进制: 前面加0,注意是零不是大写O 浮点数

传统写法

float x = 3.2; 科学计数法

float x = 3.2e3; //x的值是3200float x = 123.45e-2; //x的值是1.2345 字符

单个字符用单引号

'A’表示字符A‘AB’ 错误"AB"正确 字符串用双引号

"A"正确,因为"A"代表了’A’ '\0’的组合 常量以什么样的二进制代码存储在计算机中

整数是以补码的形式转化为二进制代码存储在计算机中实数是以IEEE754标准转化为二进制代码存储在计算机中字符的本质实际也是与整数的存储方式相同

代码规范化

代码的可读性更强[容易让自己和别人更清楚的看懂程序]使程序更不容易出错 什么是字节

字节是存储数据的单位,并且是硬件所能访问的最小单位1字节 = 8位 不同类型数据之间相互赋值的问题

暂不考虑 什么是ASCII

ASCII不是一个值,而是一种规定ASCII规定了不同的字符用哪个整数值去表示 字符的存储[字符本质上与整数的存储方式相同]

运算符

算术运算符 + - * / %(取余)关系运算符 > >= < <= != ==逻辑运算符 !(非) &&(与) ||(或)赋值运算符 = += *= /= -= 优先级别

算术 > 关系 > 逻辑 > 赋值

流程控制

流程控制【是学习C语言的第一个重点】

什么是流程控制

程序代码执行的顺序 流程控制的分类

顺序选择

定义:某些代码可能执行,也可能不执行,有选择的执行某些代码分类

ifswitch(掌握电梯程序即可) 循环

定义:分类

forwhiledo… while(主要用于人机交互) 一些小算法以及建议:

如何学习一些小算法的程序

尝试自己去编程解决它(15分钟),大部分人都自己无法解决如果解决不了,就看答案(理解部分)关键是把答案看懂,这个要花很大的精力,也是我们学习的重点看懂之后尝试自己去修改程序,并且知道修改之后程序的不同输出结果的含义,不建议看懂程序之后就立即自己敲程序照着答案去敲——>调试错误(实操部分)不看答案,自己独立把答案敲出来如果程序实在无法彻底理解, 就把它背会 浮点数的存储所带来的问题(为什么循环中更新的变量不能定义成浮点型)

float和double都不能保证可以把所有的实数都准确的保存在计算机中

例子:

#include

int main(viod)

{

float i = 99.9;

printf("%f\r\n", i);

return 0;

}

/*

----在Visual Studio Code中运行的结果---

99.900002

请按任意键继续. . .

-------------------------------------

*/

因为浮点数无法准确存储,所以衍生出下面编程问题:

有一个浮点型变量x, 如何判断x的值是否是零

​ if (|x-0.000001| < 0.000001)

​ 是零 ​ else ​ 不是零

break和continue

break:跳出最近的一层循环或者switchcontinue:跳过本次余下循环,转去判断是否需要执行下次循环 数组

为什么需要数组

为了解决大量同类型数据的存储和使用问题为了模拟现实世界 数组的分类

一维数组

注意:一维数组名不代表数组中所有的元素,一维数组名代表数组第一个元素的地址;即int a[5]初始化后,’’a‘表示’a[0]‘; 二维数组

函数

函数 【C语言的第二个重点】

为什么需要函数

避免重复性操作有利于程序模块化 什么叫函数

逻辑上:能够完成特定功能的独立的代码块

物理上:

能够接收数据[当然也可以不接受数据]

能够对接受的数据进行处理

能够将数据处理的结果返回[当然也可以不返回任何值]

总结:

函数是个工具,他是为了解决大量类似问题而设计的

函数可以当作一个黑匣子

如何定义函数

函数的返回值 函数名(函数的形参列表)

{

​ 函数的执行体

}

函数的分类

有参函数 和 无参函数

有返回值函数 和 无返回值函数

库函数 和用户自定函数

值传递函数 和 地址传递函数

普通函数 和 主函数(main数)

一个程序必须有且只能有一个主函数

主函数可以调用普通函数 普通函数不能调用主函数 普通函数可以相互调用

主函数是程序的入口,也是程序的出口

注意的问题

如果函数调用写在了函数定义的前面,则必须加函数前置声明函数前置声明。

形参和实参

个数相同 位置一一对应 数据类型必须相互兼容

如何在软件开发中合理的设计函数来解决实际问题

一个函数的功能尽量独立,单一(多模仿牛人的代码,不要总想自己敲)

函数是C语言的基本单位,类是Java,C#,C++的基本单位

常用的系统函数

变量

变量的作用域和存储方式

按作用域分

全局变量:

在所有函数外部定义的变量叫全局变量

使用范围: 从定义位置开始到整个程序结束

局部变量:

在一个函数内部定义的变量或者函数的形参都统称为局部变量

使用范围: 只能在本函数内部使用

按变量的存储方式(非重点)

静态变量自动变量寄存器变量

指针

指针的重要性(指针是C语言的灵魂)

​ 表示一些复杂的数据结构

​ 快速的传递数据,减少了内存的耗用【重点】

​ 使函数返回一个以上的值【重点】

​ 能直接访问硬件

​ 能够方便的处理字符串

​ 是理解面向对象语言引用的基础

指针的定义

地址

​ 内存单元的编号

​ 范围:4G[此是以32位OS为例,2^32B = 2^2 * 2^30B(1G) = 4G]

指针

​ 指针就是地址,地址就是指针,地址是内存单元的编号

​ 指针变量是存放地址的变量(指针也是一种数据类型)

​ 指针和指针变量是两个不同的概念

​ 但是要注意: 通常我们叙述时会把指针变量简称为指针

指针的分类

基本类型指针【重点】

附注:*的含义

乘法符号

定义指针变量 int *p;//定义了一个名字叫p的变量,int *表示p只能存放整型变量

指针运算符 该运算符放在已经定义好的指针变量的前面

如果p是一个已经定义好的指针变量

则 *p表示 以p的内容为地址的变量

指针和数组

指针和一维数组

一维数组名

一维数组是一个指针常量

它存放的是一维数组第一个元素的地址

下标和指针的关系

如果p是个指针变量,则:p[i] 永远等价于 *(p + i)

确定一个一维数组需要几个参数【如果一个函数要处理一个一维数组】

需要两个参数: 1.数组第一个元素的地址 2.数组的长度

指针变量的运算

指针变量不能相加 不能相乘 也不能相除

若两指针指向同一连续空间中不同存储单元,则两指针才可相减

指针和二维数组

指针和函数

指针和结构体

多级指针

专题:

动态内存分配【重点难点】

传统数组的缺点

数组长度必须事先定制,且只能是常整数,不能是变量传统形式定义的数组,该数组的内存无法手动释放数组的长度一旦定义,其长度不能再更改A函数定义的数组运行时可以被其他函数使用,终止后不可以(传统方式定义的数组不能跨函数使用) 为什么需要动态分配内存

动态数组很好的解决了传统数组的这4个缺陷传统数组也叫静态数组 动态内存分配举例_动态数组的构造静态内存和动态内存的比较

静态内存是由系统自动分配,由系统自动释放静态内存是在栈分配的动态内存是由程序员手动分配,手动释放动态内存是在堆分配的 跨函数使用内存的问题

结构体

为什么需要结构体

为了表示一些复杂的事物,而普通的基本类型无法满足实际要求 什么叫结构体

把一些基本类型数据组合在一起形成的一个新的复合数据类型,这个叫做结构体 如何定义结构体

3种方式,推荐使用第一种

怎么使用结构体变量

赋值和初始化

定义的同时可以整体赋初值

如果定义完之后,则只能单个的赋初值

如何取出结构体变量中的每一个成员【重点】

结构体变量名.成员名

指针变量名—>成员名

注意:p—>age在计算机内部会被转化成(*P).age

结构体变量和结构体指针变量作为函数参数传递的问题

推荐使用结构体指针变量作为函数参数来传递 结构体变量的运算

结构体变量不能相加,不能想减,也不能相互乘除

但结构体变量可以相互赋值

例子:

举例

动态构造存放信息的结构体数组

动态构造一个数组,存放学生的信息

然后按分数排序输出

枚举

什么是枚举

把一个事物存在的所用结果都一一列举出来

怎么使用枚举

枚举的优缺点

代码更安全但是书写麻烦

位运算符

位运算符:

& —— 按位与:注意与逻辑与&&区分

| —— 按位或:注意与逻辑或||区分

~ —— 按位取反:把变量所有的二进制位取反

^ —— 按位异或:相同为0,不同为1

<< —— 按位左移

i<<3 表示把i的所有二进制位左移3位,右边补零

左移n位相当于乘以2的n次方 前提是数据不丢失

面试题: A) i = i*8 B) i = i<<3 请问上述两个语句,哪个语句执行的述度快 答案: B快

同理>> —— 按位右移

i>>3 表示把i的所有二进制位左移3位,左边一般补零,也可能补1左移n位相当于除以2的n次方 前提是数据不丢失 位运算的现实意义:通过位运算符我们可以对数据的操作精确到每一位

专题:

补码 (正数:原码反码补码相同 负数:其补码为它的反码加1)

十进制转二进制

正整数转二进制

除2取余,直至商为零,余数倒叙排序

负整数转二进制

先求与该负数相对应的正整数的二进制代码,然后将所有位取反,末尾加1,不够位数时,左边补1

零转二进制

全是零

二进制转十进制

如果首位是0,则表明是正整数,按普通方法来求如果首位是1,则表明是负整数,将所有位取反,末尾加1,所得数字就是该负数的绝对值 学习目标:

一个int类型的变量所能存储的数字的范围是多少

最小负数的二进制代码是多少

最大正数的二进制代码是多少

已知一个整数的二进代码求出原始的数字

数字超过最大正数会怎样

进制转化

字符串的处理

链表

算法:

通俗定义:解题的方法和步骤

狭义定义:

广义定义:广义的算法也叫泛型

无论数据是如何存储的,对该数据的操作都是一样的

我们至少可以通过两种结构来存储数据

数组

优点 :存取速度快缺点:需要一个连续的很大的内存插入和删除元素的效率很低 链表

专业术语:

首节点:存放第一个有效数据的节点

尾节点:存放最后一个有效数据的节点

头结点:头结点的数据类型和首节点的类型是一摸一样的

头结点是首节点前面的那个节点,头结点并不存放有效数据 设置头结点的目的是为了方便对链表的操作

头指针:存放头结点地址的指针变量

优点:插入删除元素效率高不需要一个连续的很大的内存

缺点:查找某个位置的元素效率低