《C语言学习》---郝斌版---笔记
简介
学习计算机,离不开C语言的学习,而C语言学习过程中的视频课教程,目前来说,如果郝斌老师的C语言排第二,没有人敢排第一
郝斌老师的C语言教程,通俗易懂,引人发思,特别适合新手入门以及提高,强烈推荐学习
在学习过程中,记录了一些笔记,现整理出来做博客,供大家参考~
学习视频地址:《C语言学习》
学习方法论
在学习某个新知识点的时候,可以用以下方法论来进行学习:
WWHA
What:什么是A?
Why:为什么需要A?
How:怎么使用A?
Attention:需要注意哪些问题?
C语言学习推荐的参考资料:
谭浩强《C语言程序设计》
ps:这本书是又爱又恨
《C和指针》
《C专家编程》
《C陷阱与缺陷》
林锐:《高质量C/C++编程》
变量
什么是变量?
变量的本质就是内存中一段存储空间
数据存储是以“字节”(Byte)为单位,数据传输大多是以“位”(bit,又名“比特”)为单位
一个位就代表一个0或1(即二进制),每8个位(bit,简写为b)组成一个字节(Byte,简写为B),是最小一级的信息单位。
1字节(Byte) = 8位(bit)
1bit就是二进制的0和1
计算机能够处理的最小单元是 字节 而不是位
位,是由软件通过位运算符操作的
1个英文字母(不分大小写)占一个字节的空间
D十进制 B二进制 O八进制 H十六进制

基本数据类型所占字节大小:
char 1个字节
int float 4个字节
double 8个字节
可以用sizeof()验证
其他类型所占字节大小:

ASCII码关键值:
‘0’ = 48 ‘1’ = 49…
A = 65 B = 66…
a = 97 b = 98…
关于数值不够存储,溢出情况:
char 占1个字节,8位,范围是 -27 ~ 27 - 1 = -128 ~ 127
char a = 127; 使用%d打印出来是127
char a = 128; 使用%d打印出来是-128
char a = 129; 使用%d打印出来是-127
char a = 130; 使用%d打印出来是-126
scanf输入
scanf的作用:将从键盘输入的字符转化为输入控制符所规定格式的数据,然后存入以输入参数的值为地址的变量中。
sacnf("%d", &i);中,%d的作用?
在输入过程中,我们输入的都是字符1,字符2,字符3,系统接收数据,都是接收字符。系统如何能够知道我们输入的123,是一百二十三,而不是123呢?
这就需要%d的作用,让系统知道我们输入的是什么。
余数与正负符号的关系
13%3 == 1
13%-3 == 1
-13%3 == -1
-13%23 == -13
-13%-23 == -13
即,取余后的符号,只与前面的数据符号有关系
i+=1与i++的区别
i+=1;内存->寄存器->内存
i++;直接在寄存器中处理
逗号表达式
格式:
(A, B, C, D)
功能:
从左到右执行
最终表达式的值,是最后一项的值
流程控制
顺序 选择 循环
技巧:如何看懂一个程序?
1流程
2每个语句的功能
3试数(把程序运行一下)
switch
执行完一个case语句后,流程控制就转移到下一个case字句继续执行。“case”常量表达式只是起语句标号的作用,并不是在该处进行条件判断。在执行switch语句时,根据switch()中表达式的值找到与之匹配的case子句,就从此case子句开始执行下去,不再进行判断。
白话:case只是程序的入口,当找到入口后,就会顺序执行下面的所有语句(当然,case语句没啥意义,不算)

若val = 5,直接是default开始
若val=2,是从2开始的,而不是顺序执行从default开始的。
白话:就是找入口,不是顺序找;会遍历里面所有的case,有的话匹配,没有的话default。
break continue:
- break如果用于循环,是用来终止循环
- break如果用于switch,则是用于终止switch
- break不能直接用于if,除非if属于循环内部的一个子句(这句话的意思是,如果在if内部见到了break,请注意,它不作用在if上,break作用在循环中)
- 在多层循环中,break只能终止距离它最近的那个循环
- 在多层switch嵌套中,break只能终止距离它最近的switch
白话:break 是结束此次循环
continue用于跳过本次循环余下的语句,转去判断是否需要执行下次循环
白话:continue是跳过循环后面的语句,再次循环
作业题:
- 判断一个数字是否是素数?
- 判断一个数字是否是回文数?
- 编程实现求一个十进制数字的二进制形式?
- 求一个数字的每位是奇数的数字取出来组合形成新数字?
- 求一个数字倒过来的数字?
- 斐波那契数列
郝斌老师对算法程序学习的一些建议:
- 尝试自己去编程解决它,大部分人都自己无法解决。如果过了15分钟还想不出来,此时我建议你就可以看答案了。
- 如果解决不了,就看答案。关键是把答案看懂,这个要花很大的精力,也是我们学习的重点。
- 看懂之后尝试自己去修改程序,并且知道修改之后程序的不同输出结果的含义。
- 照着答案去敲。
- 调试错误。
- 不看答案,自己独立把答案敲出来。
- 如果程序实在无法彻底理解,就把它背会

是否是回文数,也可使用这种判断:
int zuiHouYiWei = 0;int shengYu = value;while (shengYu) {zuiHouYiWei = shengYu%10;shengYu = shengYu/10;sum = sum*10 + zuiHouYiWei;printf("zuiHouYiWei的值是:%d\n", zuiHouYiWei);printf("shengYu的值是:%d\n", shengYu);printf("sum的值是:%d\n", sum);printf("------------\n");}

数组
一维数组:
怎么定义一维数组:
- 为n个变量连续分配内存空间(数组的内存一定是连续分配的!)
- 所有的变量,数据类型必须相同
- 所有变量所占的字节大小必须相等
有关一维数组的操作:
初始化、赋值、排序、求最大值\最小值、倒置、查找、插入、删除
初始化:
-
完全初始化
int [5] = {1, 2, 3, 4, 5}; -
不完全初始化,未被初始化的元素自动为零
int a[5] = {1, 2, 3};//a[3] = a[4] = 0; -
不初始化,所有元素是垃圾值
int [5]; -
清零
int a[5] = {0};
错误写法:
int a[5];
a[5] = {1, 2, 3, 4, 5};//错误
原因:只有在定义数组的同时才可以整体赋值,其他情况下整体赋值都是错误的。另:a数组,并没有a[5]元素
只有在定义的时候,5表示个数;其他在任意地方出现,只是表示下标,而非个数。
两个数组之间赋值
int a[5] = {1, 2, 3, 4, 5};
int b[5];
如果要把数组a中的值全部复制给b数组,
错误的写法: b = a;
a、b代表的数组名,数组名是第一个元素的地址。
正确的写法
for (i = 0; i < 5; i++)
{b[i] = a[i];
}
二维数组:
int a[3][4] 总共12个元素,可以当做3X4看待
a[0][0] a[0][1] a[0][2] a[0][3]
a[1][0] a[1][1] a[1][2] a[1][3]
a[2][0] a[2][1] a[2][2] a[2][3]
a[i][j] 表示的是第i+1行,第j+1列的元素
初始化:
int a[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
int a[3][4] = {{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12}
};
操作:
二维数组的输出
二维数组的排序
求每一行的最大值
判断矩阵是否对称
多维数组
是否存在多维数组:不存在
原因:因为内存是线性一维的
n维数组可以当做每个元素是n-1维数组的数组
比如:int[3][4],可以看成3个一维数组,每个数组里面有4个元素。
函数
对库函数的声明是通过与 #include<库函数所在的文件的名字.h> 来实现的
return 是终止整个函数的,即,遇到return,函数就结束
变量的作用域和存储方式:
按作用域分:
- 全局变量
在所有函数外部定义的变量叫全局变量
全局变量的使用范围:从定义位置开始到整个程序结束 - 局部变量
在一个函数内部定义的变量,或者函数的形参,都统称为局部变量
局部变量的使用范围:只能在本函数内部使用
注意的问题:
全局变量和局部变量命名冲突:局部变量屏蔽全局变量
按变量的存储方式:
静态变量
自动变量
寄存器变量
如何在软件开发中合理的设计函数来解决实际问题?
一个函数的功能尽量独立、单一
多学习,多模仿牛人的代码
指针
指针就是地址
地址就是内存单元的编号
每一个小单元,有8位(8个0,或8个1)
也就是说,内存的编号不是以位算的,是以字节算的
地址一般用16进制表示(32位的操作系统中,地址是32/8=4个字节。64位系统中,地址占8个字节)
指针的定义
地址
内存单元的编号
从零开始的非负整数
范围:4G【0-4G-1】
指针
指针的本质就是 一个操作受限的 非负整数(只能-,不能+*/)
指针、指针变量
指针就是地址,地址就是指针
指针变量就是存放地址的变量 也可以说 指针变量就是存放指针的变量
例如 int *p中p就是指针变量。
需要注意:通常我们叙述时,会把指针变量简称为指针,实际上它们的含义并不一样

指针的重要性
可以表示一些复杂的数据结构;
快速的传递数据;
使函数返回一个以上的值;
直接访问硬件;
能够方便的处理字符串;
是理解面向对象语言中引用的基础
总结:指针是C语言的灵魂
指针的分类
1 基本类型指针
如何通过被调函数修改主调函数普通变量的值?
- 1 实参必须为普通变量的地址
- 2 形参必须为指针变量
- 3 在被调函数中,通过 *形参名 = …… 的方式就可以修改主调函数相关变量的值
2 指针和数组
指针 和 一维数组
一维数组名:是个指针常量,存放的是一维数组第一个元素的地址。类型为int *
数组名,是int *类型

数组下标和指针的关系
如果p是个指针变量,则p[i]永远等价于 *(p+i)
a[i] == *(a + i) int型
&a[i] == &*(a + i) == a + i int *型
然后,当i = 0时,那么
a[0] == *a int型
&a[0] == &*(a) == a; int *型
a != a[0]
a == &a[0]


确定一个一维数组需要几个参数?
需要两个参数:数组第一个元素的地址 + 数组的长度
指针变量的运算
指针变量不能 + * /
如果两个指针变量指向的是同一块连续空间中的不同存储单元,则这两个指针变量才可以相减
一个指针变量,无论它指向的变量占几个字节,该指针变量本身只占4个字节(32位下)
一个变量的地址,是使用该变量的首字节地址来表示的
指针 和 二维数组
指针和函数
指针和结构体
多级指针

动态分配内存
传统数组的缺点:
- 数组的长度必须事先制定,且只能是常整数,不能是变量
int a[5];//OK
int len = 5; int a[len];//error - 传统形式定义的数组,该数组的内存程序员无法手动释放
在一个函数运行期间,系统为该函数中数组所分配的空间会一直存在,直到该函数运行完毕时,数组的空间才会被系统释放 - 数组的长度不能在函数运行过程中动态的扩充或缩小。
- A函数定义的数组在A函数运行期间,可以被其他函数使用。但A函数运行完毕之后,A函数中的数组将无法再被其他函数使用
为什么需要动态内存分配
动态数组很好的解决了传统数组的这4个缺陷(传统数组 即 静态数组)
动态内存分配举例:动态数组的构造



静态内存和动态内存的比较
静态内存是由系统自动分配,由系统自动释放
静态内存是在栈分配的
动态内存是由程序员手动分配,手动释放
动态内存是在堆(是指堆排序)中分配的
结构体
参考:C语言知识点—结构体
进制间转换
已知十进制求二进制
-
求正整数的二进制:除2取余,直至商为零,余数倒叙排序
-
求负整数的二进制:
先求与该负数相对应的正整数的二进制代码,然后将所有位取反,末尾加1,不够位数时,左边补1
例:-3。其正整数3的二进制代码是011,取反,100,末尾加1,101。因为整数4个字节,是4*8=32位,而101只占3位,其余29位都补成1。 -
求零的二进制:全是零
已知二进制求十进制
- 如果首位是0,则表明是正整数,按普通方法来求
- 如果首位是1,则表明是负整数:将所有位取反,末尾加1,所得数字就是该负数的绝对值
- 如果全是零,则对应的十进制数字就是零
位运算符:& | ~ ^ << >>
通过位运算符,我们可以对数据的操作精确到每一位
& 按位与
| 按位或
~ 按位取反:把变量所有二进制取反
^ 按位异或:相同为0;不同为1
1^0=1 0^1 = 1
1^1= 0 0^0 = 0
<< 按位左移
>> 按位右移
十进制123,左移一位,成了1230,相当于乘10
十进制123,右移一位,成了12.3,相当于除10
同理,二进制左移1位相当于乘2;右移1位相当于除2;左移n位,相当于乘以2n
C程序测试题
1 什么叫分配内存,什么叫释放内存?
操作系统把某一块内存空间的使用权利分配给该程序 叫分配内存
操作系统把分配给该程序的内存空间的使用权利收回,改程序就不能够再使用这一块内存空间,这叫释放内存
ps:释放内存不是把该内存的内容清零
2 变量为什么必须初始化?
不初始化,则变量通常就是垃圾值
3 静态变量与动态变量的异同?
相同:都需要分配内存
不同:
静态变量是由系统自动分配,自动释放;
静态变量是在栈中分配的
函数终止后,静态变量的存储空间被系统自动释放
动态变量是由程序员手动分配,手动释放;
动态变量是在堆中分配的
程序员可以在函数执行的过程中的任何一个时刻手动释放动态变量的空间,不需要等到函数终止时才释放
4 判断下列程序语法上是否有错误
A int *p; *p = 10; 错
B char *p; char ch = A; p = &ch; 对 错 char ch = ‘A’;
C int i,j; i=j=0; int *p; p=&i; 对
D int *p; int **q; q=&p; 对
E int *p; int i = 5; p=&i; *p = 10; 对
二进制全部为零的含义 —000000000000的含义
1 数值零
2 字符串结束标记符’\0’
3 空指针NULL
NULL本质也是零,但这个零不代表数字零,而表示的是内存单元的编号零(是个地址)
计算机规定:以零为编号的存储单元的内容不可读、不可写
相关文章:
《C语言学习》---郝斌版---笔记
简介 学习计算机,离不开C语言的学习,而C语言学习过程中的视频课教程,目前来说,如果郝斌老师的C语言排第二,没有人敢排第一 郝斌老师的C语言教程,通俗易懂,引人发思,特别适合新手入门…...
Python(32):字符串转换成列表或元组,列表转换成字典小例子
1、python 两个列表转换成字典 字符串转换成列表 列表转换成字典 column "ID,aes,sm4,sm4_a,email,phone,ssn,military,passport,intelssn,intelpassport,intelmilitary,intelganghui,inteltaitonei,credit_card_short,credit_card_long,job,sm4_cbc,sm4_a_cbc" …...
CentOS 7 安装私有平台OpenNebula
目录 一、配置yum源 二、配置数据库MySQL 2.1 安装MySQL 2.2 修改MySQL密码 2.3 创建项目用户和库 三、安装配置前端包 四、设置oneadmin账号密码 五、验证安装 5.1 命令行验证安装 5.2 数据存放位置 5.3 端口介绍 5.4 命令介绍 六、访问 6.1 设置语言 6.2 创建主…...
(aiohttp-asyncio-FFmpeg-Docker-SRS)实现异步摄像头转码服务器
1. 背景介绍 在先前的博客文章中,我们已经搭建了一个基于SRS的流媒体服务器。现在,我们希望通过Web接口来控制这个服务器的行为,特别是对于正在进行的 RTSP 转码任务的管理。这将使我们能够在不停止整个服务器的情况下,动态地启动…...
基于STM32微控制器的四轮智能小车控制系统设计
标题:基于STM32微控制器的四轮智能小车控制系统设计与实现 摘要: 本文针对移动机器人领域的应用需求,详细介绍了基于STM32系列单片机(以STM32F103C8T6为例)为核心的四轮小车控制系统的设计和实现过程。该系统集成了电…...
JPA的复杂查询包括一对多多对一和多对多的查询
1. 多表关联查询和排序 假设我们有两个实体类:Customer和Order,它们之间是一对多的关系,即一个客户可以有多个订单。我们想要查询某个客户的所有订单,并按订单金额进行降序排序。 Entity Table(name "customers") pu…...
电脑文件mfc100u.dll丢失的解决方法分析,怎么修复mfc100u.dll靠谱
mfc100u.dll丢失了要怎么办?其实很多人都遇到过这样的电脑故障吧,说这个mfc100u.dll文件已经不见了,然后一些程序打不开了,那么这种情况我们要怎么解决呢?今天我们就来给大家详细的说说mfc100u.dll丢失的解决方法。 一…...
从DETR到Mask2former(2): 损失函数loss function
DETR的损失函数包括几个部分,如果只看论文或者代码,比较难理解,最好是可以打断点调试,对照着论文看。但是现在DETR模型都已经被集成进各种框架中,很难进入内部打断掉调试。与此同时,数据的label的前处理也比…...
Java21 + SpringBoot3集成WebSocket
文章目录 前言相关技术简介什么是WebSocketWebSocket的原理WebSocket与HTTP协议的关系WebSocket优点WebSocket应用场景 实现方式1. 添加maven依赖2. 添加WebSocket配置类,定义ServerEndpointExporter Bean3. 定义WebSocket Endpoint4. 前端创建WebSocket对象 总结 前…...
鲸鱼优化算法WOA改进预告
鲸鱼优化算法(Whale Optimization Algorithm,WOA)是一种基于自然界中鲸鱼群体行为的启发式优化算法。这个算法模拟了鲸鱼的觅食行为和社会行为,通过模拟这些行为来解决优化问题。 以下是鲸鱼优化算法的一些关键特点和步骤&#x…...
Nightingale 夜莺监控系统 - 告警篇(3)
Author:rab 官方文档:https://flashcat.cloud/docs/content/flashcat-monitor/nightingale-v6/usage/alert/alert-rule/ 目录 前言一、配置1.1 创建钉钉机器人1.2 n9e 创建通知用户1.3 n9e 创建团队(组)1.4 将通知用户添加团队1.…...
【LeetCode2696】删除子串后的字符串最小长度
1、题目描述 【题目链接】 标签:栈 、字符串、模拟 难度:简单 给你一个仅由 大写 英文字符组成的字符串 s 。 你可以对此字符串执行一些操作,在每一步操作中,你可以从 s 中删除 任一个 “AB” 或 “CD” 子字符串。 通过执行操作…...
VMware安装CentOS7虚拟机
VMware 安装 获取 VMware 安装包 下载地址:链接:https://pan.baidu.com/s/1ELR5NZa7rO6YVplZ1IUigw?pwdplz3 提取码:plz3 包括:当然,也可以自己去别的地方下载,WMware 版本都差不多,现在用的比…...
Linux第22步_安装CH340驱动和串口终端软件MobaXterm
开发板输出信息通常是采用串口,而计算机通常是USB接口,为了让他们之间能够交换数据,我们通常采用USB转串口的转换器来实现。目前市场上的串口转换器大多是采用CH340芯片来实现的,因此我们需要在计算中安装一个CH340驱动程序&#…...
Elasticsearch 地理空间搜索 - 远超 OpenSearch
作者:来自 Elastic Nathan_Reese 2021 年,OpenSearch 和 OpenSearch Dashboards 开始作为 Elasticsearch 和 Kibana 的分支。 尽管 OpenSearch 和 OpenSearch Dashboards 具有相似的血统,但它们不提供相同的功能。 在分叉时,只能克…...
USB micro输入口中三个问题详解——差分信号、自恢复保险丝SMD1210P050TF、电容滤波
前言:本文对USB micro输入口中遇见的三个问题进行详解:差分信号、自恢复保险丝SMD1210P050TF、电容滤波 目录: 差分信号 自恢复保险丝SMD1210P050TF 电容滤波 如下图,USB为U-F-M5DD-Y-1型号(9个引脚,除…...
mysql原理--undo日志1
1.事务回滚的需求 我们说过 事务 需要保证 原子性 ,也就是事务中的操作要么全部完成,要么什么也不做。但是偏偏有时候事务执行到一半会出现一些情况,比如: (1). 事务执行过程中可能遇到各种错误,比如服务器本身的错误&…...
Zookeeper系列(一)集群搭建(非容器)
系列文章 Zookeeper系列(一)集群搭建(非容器) 目录 前言 下载 搭建 Data目录 Conf目录 集群复制和修改 启动 配置示例 测试 总结 前言 Zookeeper是一个开源的分布式协调服务,其设计目标是将那些复杂的且容易出错的分…...
【高等数学之泰勒公式】
一、从零开始 1.1、泰勒中值定理1 什么是泰勒公式?我们先看看权威解读: 那么我们从古至今到底是如何创造出泰勒公式的呢? 由上图可知,任一无穷小数均可以表示成用一系列数字的求和而得出的结果,我们称之为“无穷算法”。 那么同理我们想对任一曲线来…...
奇异值分解在图形压缩中的应用
奇异值分解在图形压缩中的应用 在研究奇异值分解的工程应用之前,我们得明白什么是奇异值?什么是奇异向量? 奇异值与奇异向量 概念:奇异值描述了矩阵在一组特定向量上的行为,奇异向量描述了其最大的作用方向。 奇异值…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...
中医有效性探讨
文章目录 西医是如何发展到以生物化学为药理基础的现代医学?传统医学奠基期(远古 - 17 世纪)近代医学转型期(17 世纪 - 19 世纪末)现代医学成熟期(20世纪至今) 中医的源远流长和一脉相承远古至…...
