《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是跳过循环后面的语句,再次循环

作业题:

  • 判断一个数字是否是素数?
  • 判断一个数字是否是回文数?
  • 编程实现求一个十进制数字的二进制形式?
  • 求一个数字的每位是奇数的数字取出来组合形成新数字?
  • 求一个数字倒过来的数字?
  • 斐波那契数列

郝斌老师对算法程序学习的一些建议:

  1. 尝试自己去编程解决它,大部分人都自己无法解决。如果过了15分钟还想不出来,此时我建议你就可以看答案了。
  2. 如果解决不了,就看答案。关键是把答案看懂,这个要花很大的精力,也是我们学习的重点。
  3. 看懂之后尝试自己去修改程序,并且知道修改之后程序的不同输出结果的含义。
  4. 照着答案去敲。
  5. 调试错误。
  6. 不看答案,自己独立把答案敲出来。
  7. 如果程序实在无法彻底理解,就把它背会

在这里插入图片描述
是否是回文数,也可使用这种判断:

    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");
    }

在这里插入图片描述


数组

一维数组:

怎么定义一维数组:

  1. 为n个变量连续分配内存空间(数组的内存一定是连续分配的!)
  2. 所有的变量,数据类型必须相同
  3. 所有变量所占的字节大小必须相等

有关一维数组的操作:
初始化、赋值、排序、求最大值\最小值、倒置、查找、插入、删除

初始化:

  • 完全初始化
    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位下)
一个变量的地址,是使用该变量的首字节地址来表示的

指针 和 二维数组

指针和函数

指针和结构体

多级指针

在这里插入图片描述


动态分配内存

传统数组的缺点:

  1. 数组的长度必须事先制定,且只能是常整数,不能是变量
    int a[5];//OK
    int len = 5; int a[len];//error
  2. 传统形式定义的数组,该数组的内存程序员无法手动释放
    在一个函数运行期间,系统为该函数中数组所分配的空间会一直存在,直到该函数运行完毕时,数组的空间才会被系统释放
  3. 数组的长度不能在函数运行过程中动态的扩充或缩小。
  4. 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本质也是零,但这个零不代表数字零,而表示的是内存单元的编号零(是个地址)
计算机规定:以零为编号的存储单元的内容不可读、不可写

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/316087.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

jmeter和meterSphere如何使用第三方jar包

工具引用jar包语言都是beanshell 问题起因&#xff1a;metersphere 接口自动化实现过程中&#xff0c;如何实现字符串加密且加密方法依赖第三方库&#xff1b; 使用语言&#xff1a;beanshell脚本语言&#xff0c;java语言 使用工具&#xff1a;idea jmeter metersphere 1.首…

2024年甘肃省职业院校技能大赛信息安全管理与评估 样题一 模块一

竞赛需要完成三个阶段的任务&#xff0c;分别完成三个模块&#xff0c;总分共计 1000分。三个模块内容和分值分别是&#xff1a; 1.第一阶段&#xff1a;模块一 网络平台搭建与设备安全防护&#xff08;180 分钟&#xff0c;300 分&#xff09;。 2.第二阶段&#xff1a;模块二…

大小鼠”专项”训练实验跑台—ZL-013小动物实验跑步机

运动疲劳的研究一直备受研究学者的关注&#xff0c;运动性疲劳动物模型也已经成为运动性疲劳研究的重要途径。运动性疲劳与一般的疲劳不同&#xff0c;其是在运动过程中发生的一种疲劳症候&#xff0c;不同的运动方式对疲劳产生的程度不同&#xff0c;对动物机体产生的影响也大…

【MyBatis】动态SQL

文章目录 前言增加操作\<trim>标签查询操作\<where>标签修改操作\<set>标签删除操作\<foreach>标签\<include>标签 前言 动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架&#xff0c;你应该能理解根据不同条件拼接 SQ…

云原⽣组件Nacos新型红队手法研究

组件简介 Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service的首字母简称&#xff0c;一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。 Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集&#xff0c;帮助您快…

C++代码重用:继承与组合的比较

目录 一、简介 继承 组合 二、继承 三、组合 四、案例说明 4.1一个电子商务系统 4.1.1继承方式 在上述代码中&#xff0c;Order类继承自User类。通过继承&#xff0c;Order类获得了User类的成员函数和成员变量&#xff0c;并且可以添加自己的特性。我们重写了displayI…

java进阶||jdk进阶之循环

从18年学java到现在除了各种各样的数据类型和集合烧不了要遍历这些变量, for循环这时就少不了啦(当然还有8后引入的神器泛型) 先来看一段精髓业务代码, 使用了多个新特性当然也少不了循环和分支判断 代码较长解析在后面 private CommonPage<List<Object>> handle…

NX二次开发PK获取对象类型

PK_ENTITY_ask_class(),获取对象类型建议用这个函数&#xff0c;比较通用&#xff0c;包含所有对象类型&#xff0c;可以替代UF_MODL_ask_edge_type(),UF_MODL_ask_body_type(),UF_MODL_ask_face_type()等函数 PK_ENTITY_t entity; PK_CLASS_t PK_TYPE; PK_ENTITY_ask_class(e…

ubuntu 22 搭建git服务

第一步&#xff0c;安装git&#xff1a; sudo apt-get install git 创建用户信息 git config --global user.name soft 第二步&#xff0c;创建一个git用户&#xff0c;用来运行git服务&#xff1a; sudo adduser git 创建git仓库的存储目录、更改文件目录属主为代码仓库…

观测云产品更新 | 日志、场景仪表板、监控器等

观测云更新 用户访问监测 &#xff08;RUM &#xff09; 公网 Dataway 支持 ip 转换成地理位置信息。 日志 > 查看器详情页 1、新增 BPF 网络日志采集及日志详情页&#xff0c;支持 Json 格式转化&#xff1b; 2、上述 1 中的日志详情页中新增可读的展示模式&#xff0c…

爬虫—响应页面乱码问题解决方法

爬虫—响应页面乱码问题解决方法 案例&#xff1a;腾牛网图片抓取 源代码如下&#xff1a; import requestsurl https://www.qqtn.com/wm/meinvtp_1.html headers {user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) …

牛客周赛 Round 1 解题报告 | 珂学家 | 分类计数 + 同余DP

前言 生于生时&#xff0c;亡于亡刻。遵从自心&#xff0c;尽人之事。 整体评价 终于等来了侧重面试的比赛&#xff0c;而且题量刚刚好&#xff0c;不超纲&#xff0c;不涉及算法竞赛。 第一场的比赛&#xff0c;感觉题目出的比较典&#xff0c;A是简单模拟&#xff0c;B则是…

springcloud sleuth分布式请求链路跟踪

简介 在微服务框架中&#xff0c;一个由客户端发起的请求在后端系统中会经过多个不同的的服务节点调用来协同产生最后的请求结果&#xff0c;每一个前段请求都会形成一条复杂的分布式服务调用链路&#xff0c;链路中的任何一环出现高延时或错误都会引起整个请求最后的失败. S…

【深度学习每日小知识】Logistic Loss 逻辑回归

逻辑回归的损失函数 线性回归的损失函数是平方损失。逻辑回归的损失函数是对数损失&#xff0c;定义如下&#xff1a; L o g L o s s ∑ ( x , y ) ∈ D − y log ⁡ ( y ′ ) − ( 1 − y ) log ⁡ ( 1 − y ′ ) LogLoss\sum_{(x,y)\in D}-y\log(y)-(1-y)\log(1-y) LogLoss…

黑马程序员——2022版软件测试——乞丐版——day02

目录&#xff1a; 解决穷举场景 等价类划分法案例&#xff08;qq合法验证&#xff09;案例&#xff08;城市电话验证&#xff09;总结&#xff08;应用场景&#xff09;解决边界限制问题 步骤案例1案例2总结解决多条件有依赖关系测试 介绍步骤案例&#xff08;订单&#xff09…

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK实现相机的高速图像保存(C#)

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK实现相机的高速图像保存&#xff08;C#&#xff09;&#xff09; Baumer工业相机Baumer工业相机的图像高速保存的技术背景Baumer工业相机通过NEOAPI SDK函数图像高速保存在NEOAPI SDK里实现线程高速图像保存&#xff1a;工业相机高…

LLM主流框架:Causal Decoder、Prefix Decoder和Encoder-Decoder

本文将介绍如下内容&#xff1a; transformer中的mask机制Causal DecoderPrefix DecoderEncoder Decoder总结 一、transformer中的mask机制 在Transformer模型中&#xff0c;mask机制是一种用于在self-attention中的技术&#xff0c;用以控制不同token之间的注意力交互。具体…

Debezium发布历史64

原文地址&#xff1a; https://debezium.io/blog/2019/07/12/streaming-cassandra-at-wepay-part-1/ 欢迎关注留言&#xff0c;我是收集整理小能手&#xff0c;工具翻译&#xff0c;仅供参考&#xff0c;笔芯笔芯. 在 WePay 上流式传输 Cassandra - 第 1 部分 七月 12, 2019 …

HackTheBox - Medium - Linux - Faculty

Faculty Faculty 是一台中型 Linux 机器&#xff0c;具有 PHP Web 应用程序&#xff0c;该应用程序使用的库容易受到本地文件包含的影响。利用该库中的 LFi 会泄露一个密码&#xff0c;该密码可用于通过 SSH 以名为“gbyolo”的低级用户身份登录。用户“gbyolo”有权作为“dev…

Leetcode 剑指 Offer II 061. 查找和最小的 K 对数字

题目难度: 中等 原题链接 今天继续更新 Leetcode 的剑指 Offer&#xff08;专项突击版&#xff09;系列, 大家在公众号 算法精选 里回复 剑指offer2 就能看到该系列当前连载的所有文章了, 记得关注哦~ 题目描述 给定两个以升序排列的整数数组 nums1 和 nums2 , 以及一个整数 k…
最新文章