C语言基础笔记

【C语言基础学习笔记】一、初始C语言(3) 说明:我是一个初学c语言的小白,很多地方都不是很理解,所以就会自己动手敲代码进行相应的推理验证,希望可爱的你在看到这些步骤时,不要嫌弃我啰嗦。(比如吐槽:这作者咋这样呀,这么简单的还要敲代码验证,真菜呀!…我:好吧,我不装了,我摊牌了,我确实菜,真的菜,咋滴啦,还不允许初学者菜呀!) EOF-- - end of file 文件结束标志 值: - 1 提示:本小结是初始C语言最后一小部分内容,之后会有一个初始C语言总结的文章,包含初始C语言(1)(2)(3)复习专用的思维导图,一些用于编程练习的ca 阅读详情

1.字符'A'的值为65,字符'a'的值为97,空格的值为32

2.c语言规定字符串型常量的结尾需要加一个字符串结束标志,所以比如"CHINA"5个字符其实是占用了6个字节,如图所示:

3.强制类型转换

当你的左右两个数都是整型时,做的其实是整型运算,5/2=2然后再将2转换成浮点型2.000000。

当我们在运算之前先将整型i进行强制类型转换成float浮点型,这样运算出来的结果就是对的了。

4.printf函数

printf函数可以输出各种类型的数据,其原理是将这些类型的数据格式化成字符串之后,放入到标准的输出缓冲区,然后展示到屏幕面前

5.printf函数的具体代码格式

%c 字符;%d 带符号整数;%f 浮点数;%s 字符串

6.printf函数的格式化输出(空格补齐)

通过上面两张对比图可以看到printf函数可以使输出的结果数据右对齐,如果需要左对齐使用%-3d即可。这里的3表示的是不够三位的使用空格补齐,超过三位的不变。如下图所示这里的%5.2f表示的是不够五位补空格,小数点后面保留两位。

7.整型进制转换

123(十进制)——>001111011(二进制)——>173(八进制)——>7b(16进制)

十进制的数字转换成二进制的方法是将十进制的数字不断除以2直到0为止然后从后往前取余数,这里要注意的是首位数字的0表示正数,1表示负数。如下图所示转换过程。

printf函数可以打印出不同进制的数字:

%d:十进制;%o:八进制;%x:16进制

如果想知道二进制需要在内存试图里面看到,而这里本来应该是0000007b但是实际的存储是7b000000,原因是cpu采用了小端方式进行数据存储,因此地位在前、高位在后。

8.scanf函数

scanf之所以是会阻塞等待你的输入是因为输入缓冲区里面是空的

一般格式如下:

使用注意:当我们需要输出char类型的数据时,需要注意下面这种情况

代码:

结果:

scanf是从输入缓冲区里面读取字符的,所以一开始读取i的值的时候只是把i的值读取了但是换行符\n没有读取,但是scanf读取下一个数据的时候发现是字符类型的,所以就把换行符\n读取了。

过程:

解决方法:在读取字符之前加一个空格

代码:

结果:

9.算数运算符,关系运算符和逻辑运算符

sizeof(数据)是运算符

逻辑非的优先级高于算术运算符,逻辑与和逻辑或的优先级低于关系运算符

算数运算符:+,-,*,/

关系运算符号:>,<,=

逻辑运算符号:&&,||,!

10.数组的定义和初始化

上图我们可以看到数组的大小是要一开始就需要给定的,并且不能使用常量来定义。

当你初始化数组的大小是大于你实际储存内部的数据时,其余的部分会为0,由此我们可以写出直接赋值全为0的数组。

11.数组的访问越界

代码中并未改变i的值但是最后i的值却变了,我们打开内存视图可以看到i的值存储的位置就是a[6]存储的位置,所以a[6]赋值的7便成为了i的值,这就是访问越界的危险性

12.数组的传递

代码:

结果:

当给自定义函数进行数组传递时可以看到,明明将数组传递过去了,但是循环打印的结果却打印了数组5个值当中的2个值,于是加上打印a的值可以看出我们传递的数组其实是一串数字,那这一串数字其实是这个数组在内存中的地址。所以其实当你用数组名传递的时候传递的其实是数组的地址,并且函数的调用是用值来传递的,所以在print函数中数组名被弱化成了指针。由于电脑是64位的所以指针的大小是8个字节,int整型是4个字节所以算出来的大小为i<2,最终只打印出了两个值。

注意点:1.数组名作为实参传递到子函数的时候传递的是数组的起始地址

2.数组内的数据可以被子函数进行改变

13.字符数组的初始化和使用

这两种初始化方式,推荐写第二种;并且定义字符数组的大小需要比实际存储的数据要多一个,这是因为字符数组需要存贮一个结束符‘\0’。

14.scanf读取字符串

使用scanf读取字符串的时候,如果有空格只能分开来读取,scanf遇到空格会自动停止读取,如下图所示

15.gets函数和puts函数

当读取字符串时,一般使用gets来读取,gets是遇到\n换行符停止读取;gets是将\n换行符转换成'\0'实际并未存储\n换行符。

16.str系列字符串操作函数

代码:

结果:

(1)strlen统计的是字符串长度并不是字符数组长度。arr字符数组的长度是20,但是里面只存储了hello这5个字符,所以strlen得出的值为5;

(2)strcat(拼接字符串)和strcpy(拷贝字符串),它们的第一个参数必须是字符数组名不能是字符串常量(比如"hello");

(3)strcmp(a,b)比较a和b的大小是看它们的ascall码值不是比较它们的长度,

a>b结果为正整数,a=b结果为0,a<b结果为负整数;

17.指针

指针其实实际上就是地址,但是存储的是起始地址,如下图所示。比如int类型的指针变量存储的是0x00000002的地址,然后根据定义的数据类型来决定要访问多少个字节,int类型就从起始位置开始访问4个字节,char类型就访问一个字节;

指针的定义和初始化,可以联想一下i_pointer相当于藏宝图,然后利用*(取值)去找宝藏,最终通过间接访问去修改数据;

指针的大小

指针本身的大小是不变的,只与操作系统的位数有关,64位操作系统的指针大小是8个字节,32位操作系统的指针大小是4个字节;但是加入*(取值)符号之后的大小就是指针变量基类型的大小,如int *i_pointer就是4个字节,char *c_pointer是1个字节;

注意:int *a,*b,*c;这种才是定义三个指针变量的正确方法

18.指针的传递

上述代码的结果,可以看出当利用子函数去改变主函数定义变量的值时这样的写法是失败了的。本质是当执行change函数时又创建了一个空间去储存j的值,实际改变的是j的值;

利用指针变量来修改变量的值,代码如下:

此时j是指针变量,里面存储的是i的地址,在子函数change中利用指针变量访问i的地址,然后进行修改;(函数的调用是值传递,但是传递地址实际上并未违反规则,实际的过程是 int *j=&i)

19.指针的偏移

一般如果定义一个 int i = 1,i+1的结果会是2;但是当定义int *p ,p+1的值会是多少呢?

可以看到当p+1的时候并不是在p原先的值上面+1,而是根据指针的基类型来进行偏移

当数组名作为实参传递给子函数时,是被弱化为指针的

20.指针与动态内存申请

一般在定义变量的时候,它的存储位置是在栈空间的,当使用malloc去申请空间时,数据的存储是在堆空间。申请动态内存的代码如下:

注意点(1)malloc参数是申请空间的大小,返回的是空类型的指针,所以要进行强制转换;接收的指针不能为空类型的指针是因为void*类型的指针是不能进行偏移的;

    (2)malloc是申请的堆上面的空间,需要手动free释放空间

    (3)free释放空间时p的位置不能发生改变,必须是malloc返回的地址

    (4)指针本身的大小和指向空间的大小是不同的,指针本身的大小是固定的不会改变,64位操作系统是8个字节32位操作系统是4个字节

21.堆和栈的差异

栈空间的内存是操作系统释放的,堆空间的内存是需要手动free释放(或者程序结束)的;

代码:

结果:

当printf_stack函数调用结束时,系统自动释放了空间,所以当在主函数打印时会乱码;但是printf_malloc函数调用结束时没有手动free释放空间,在主函数依旧可以打印。

22.函数的声明和定义

注意点:

(1)函数可以嵌套调用但不能嵌套定义

(2)其他函数不能调用main函数,main函数是由主函数进行调用的

23.递归调用

当函数调用的函数是自己本身时称之为递归函数,递归一定要有结束条件否则会形成死循环

例子1:求n的阶乘(利用递归的方式)

递归的思路:

(1)找公式:n!=(n-1)!*n

(2)循环结束条件:n=1时n!=1;n=0时n!=0;n>=0;

代码:

例子2:青蛙跳台阶

青蛙一次只能眺一格台阶或者两格台阶,如果有n个台阶青蛙有多少种跳法

(1)找公式

在跳到最后一个台阶之前我们只有两种可能性,一种是在倒数第一个台阶,一种是在倒数第二个台阶;所以可以推断出公式为:f(n)=f(n-1)+f(n-2);

(2)结束条件

首先n不可能小于0的,所以n>=0;其次公式中很明显有两个特殊的数字1和2,n=1时f(1)=1,n=2时f(2)=2,然后就是正常公式的算法了;

代码:

24.局部变量和全局变量

全局变量存储的空间不在栈和堆上,而是在数据段上;

当局部变量和全局变量重名时,系统规定采取就近原则;如下图代码所示main中的i匹配的时int i = 5,print函数匹配的是int i形参的值,而实参传递给形参的值为3,所以打印出来的就是main中i=5,print中i=3

形式参数在函数没有被调用时是不占内存空间的

25.结构体的声明和使用

代码:

结构体类型的声明结尾是以:结尾,结构体访问成员用.来进行访问。

当使用scanf输入字符数组时不需要使用&符号,数组名就是存放的地址

结果:

结构体数组的声明和使用:

代码

结果:

26.结构体对齐的三大法则:

1 自然对齐规则:结构体的成员将按照自然对齐原则来排列。自然对齐要求每个成员的地址是其数据类型大小的整数倍。例如,一个int类型的成员通常会被对齐到4字节边界(整除4),而一个double类型的成员通常会被对齐到8字节边界,

2 填充字节:如果一个成员的大小不是对齐边界的整数倍,编译器通常会在其后添加一些填充字节,以确保下一个成员能够正确对齐。填充字节的大小取决于编译器和目标平台,通常是1字节或更多。

3 结构体的总大小:结构体的总大小通常等于其最大成员的大小的整数倍。这是为了确保结构体数组的每个元素都按照相同的规则对齐

代码:

结果:

student_type1成员大小分别是8,4,2应该是14个字节结果确实16个字节,实际在内存中存储的是16个字节如下图所示,根据结构体对其法则当是14个字节时不符合结构体的总大小是最大成员大小的整数倍,所以填充了2个字节

而student_type2成员大小分别是4,1,2应该是7个字节,但是在实际存储中可以看到当存储完char类型的数据后,自动填充了1个字节,然后才存储的short类型的数据;这是因为不满足自然对其规则,如果不填充1个字节那么short数据的地址就不是是其数据类型大小的整数倍不能被2整除(意思是假设现在处于地址为14的位置能被short大小为2整除,如果不填充1个字节就在地址为13的位置不能被short大小为2进行整除)

27.结构体指针

通过结构体指针访问结构体成员有两种方式

方式1:(*p).这里加()的原因是运算符.的优先级比*的优先级要高

方式2:p->这种方式为常用方式,方式1不推荐使用

结构体指针使用malloc申请空间,对成员赋值并且访问。这里要注意给字符串赋值需要使用strcpy不能直接进行赋值。

28.typedef的使用

typedef相当于重命名的作用,就想许多作者一样有自己的名字也有笔名,那typedef就是将周树人重命名为鲁迅,从此鲁迅就是周树人周树人就是鲁迅。stu=struct student;pstu=struct student*(注意是pstu不是*ptsu)

29.c++引用

c语言中为什么要使用c++的引用?

因为它太好用了,可以帮助我们理解一些难的代码,其次c++完全兼容c语言

什么是引用?

当需要改变主函数里面变量的值时就加上&引用,不改变就不加

30.子函数改变主函数中一级指针变量

当利用指针改变主函数指针变量的值时,结果发现程序已经崩溃,并没有改变变量的值

当换成引用时,结果显示是可以改变的;这其实就是引用的目的,因为*p=NULL实际存储的是0,值为0的时候内存是不能访问的,就相当于现在给你一张藏宝图但是藏宝图显示的位置没有宝藏;同时也要注意&引用的写法:引用必须和变量名紧邻

31.c++引用案例

案例一:引用改变结构体成员的值

没有加&引用时,主函数的stu s在内存中创建了一个空间,子函数的s也在内存中创建了一个空间,所以子函数改变的是自己创建s的值,主函数的值不会改变

当在子函数的形参中加上了&引用符,结果显示主函数的值改变了;至于其原理和过程不重要也不考,你只需要知道当加上了&引用符号的时候在子函数中操作变量就相当于在主函数上操作变量。

案例二:改变结构体指针指向的malloc申请内存中成员的值

通过下面的代码可以看出,在并没有使用引用&的情况下,依然是改变了主函数中的值

原因就是在子函数并没有改变指针p的值而是利用指针p去间接访问malloc申请的内存空间中的值,所以不需要加引用&

【C语言基础学习笔记】一、初始C语言(1) 说明:我是一个初学c语言的小白,很多地方都不是很理解,所以就会自己动手敲代码进行相应的推理验证,希望可爱的你在看到这些步骤时,不要嫌弃我啰嗦。(比如吐槽:这作者咋这样呀,这么简单的还要敲代码验证,真菜呀!…我:好吧,我不装了,我摊牌了,我确实菜,真的菜,咋滴啦,还不允许初学者菜呀!) 1.第一个c语言程序 #include<stdio.h> int main() { printf("hello world!\n"); return 0; } //所有的c语言程序都有相同的一个框架 int 阅读详情

相关推荐

一文说清Arduino如何实现舵机平滑转动(机器人场景)

深入讲解如何利用arduino控制舵机转动,实现机器人场景中的平稳运动。通过代码优化与脉冲宽度调节,让舵机动作更精准流畅,适用于各类自动化项目。

weixin_35706255的博客 899

C语言基础学习笔记

此博文是整理本人初入编程世界学习C语言的经历,零基础想学习C语言的可参考本文的学习方式,内容包含视频+笔记+思维导图总结,根据视频资源编写自己见解的学习笔记,再从笔记中提炼总结思维导图。笔记看得云里雾里是正常的,一是需要配合视频,二是因为写笔记时是想到哪里记到哪里,每个人侧重点不同,笔记仅供参考。

weixin_45068267的博客 2129

Megatron单机多卡Qwen2.5:pre-train+sft

英伟达:https://github.com/NVIDIA/Megatron-LM/releases/tag/core_r0.8.0阿里:https://github.com/alibaba/Pai-Megatron-Patch/releases/tag/v0.10.2。

weixin_46873015的博客 2180

C 语言基础笔记 p1

起源:1972 年由丹尼斯・里奇(Dennis Ritchie)在贝尔实验室开发,最初用于编写 UNIX 操作系统。特点面向过程的编程语言,结构化强,逻辑清晰。高效性:接近底层硬件,执行速度快,适合系统级开发。可移植性:代码能在不同平台(Windows、Linux、Mac)上运行(需重新编译)。功能强大:支持指针、位运算等底层操作,是很多高级语言的基础(如 Python、Java 的底层部分用 C 实现)。应用场景:操作系统、嵌入式开发、驱动程序、游戏引擎、数据库等。c运行。

cindddwww的博客 2258

代码审计工具学习之Seay(安装以及初步认识)

目录 1.1名词解释 1.2代码审计的重要性 1.3代码审计的步骤 1.4代码审计的内容 1.5常见的代码审计工具 2 Seay 2.1什么是Seay 2.2Seay的安装过程 3典型漏洞分析 3.1什么是命令注入漏洞 3.2 如何理解命令注入漏洞 3.3 如何防御命令注入漏洞 4 利用工具对命令注入漏洞进行分析 4.1DVWA靶场命令注入漏洞分析 4.2 Pikachu靶场命令注入漏洞分析 1.1名词解释 软件代码审计是对编程项目中源代码的全面...

weixin_52515588的博客 2万+

6-3 根据派生类写出基类(Java解法)(PTA)

主要是看main函数里调用了什么方法和输出样例,一一对应一下有思路再写就很简单.建议使用IDEA自动生成,可以少写很多代码。

u012137663的博客 1142

C语言基础知识复习笔记

这是UESTC大一程序设计与算法基础1的期末复习笔记

m0_73174219的博客 982

高性能优化的本质

在很早之前,处理器性能的提升一般是通过减小元器件的尺寸,增加元器件的数量,提高主频来实现,这也是摩尔定律所说的,但是由于功耗的影响,主频不能一直增加。后来,由于英伟达的GPU的并行计算的出现,逐渐打破摩尔定律,人们利用多核,SIMD,SIMT来处理大量相同计算的数据,这极大的提高了效率。计算机的算力得到了巨大的提升,但是并行是困难的,对于有数据依赖的程序来说,处理并行是一件及其困难的事,但对于一些简单的数学库的计算,并行的实现相对简单。

发狂的小花的博客 274

嵌入式学习笔记之C语言基础

C语言是世界上最流行、使用最广泛的高级程序设计语言之一,广泛用于系统与应用软件的开发。具备很强的数据处理能力、高效、灵活、功能丰富、表达力强和较高的移植性等特点。操作系统是计算机系统的核心,如 Unix、以及 Windows 的部分内核,都是使用 C 语言进行开发的。C语言能够直接访问硬件资源,可以实现对硬件设备的驱动程序开发,使得计算机能够识别和使用各种硬件,如显卡、声卡、网卡等。

2402_83192253的博客 1108

19、时间触发通信与时间触发以太网技术解析

本文深入解析了时间触发通信和时间触发以太网(TTEthernet)技术,涵盖了其在实时系统中的应用,特别是安全关键领域如航空航天。文章详细介绍了TTEthernet的通信服务、协议参数化、时钟同步机制、诊断服务、故障隔离方法以及验证工作,并通过示例配置展示了其灵活性和可扩展性。TTEthernet通过引入确定性时间触发通信范式,在同一物理网络上实现了时间触发、速率受限和尽力而为三种流量类别的集成,为分布式实时系统提供了高可靠性和实时性保障。

efc12345678的博客 115

AUTOSAR从入门到精通-汽车电子电气架构(EEA)(二)

需求的传递并非完全是瀑布式的单向传递,而是双向的,只有被下游接受了的需求才是有效的需求,而且,下游是可以反向对上游提出需求的。当街区的设计完成之后,接下来要做的就是每栋建筑的详细设计,建筑的设计者发布的图纸中规定了房屋的主要结构、所在位置与周边环境的相互关系,以及屋中各种组件的位置与相互之间结合的关系,比如砖混结构、房屋的具体位置和朝向、卧室与客厅的相对位置与尺寸、马桶在卫生间中的位置等,还会对各种建筑材料的选取原则给出具体的标准,比如水泥的标号,钢筋的型号,各种电线的等级要求等等。

getusushu的博客 373

C语言基础:第02天笔记

自动类型转换是编译器根据上下文自动进行的类型转换,遵循一定的规则。强制类型转换需要程序员明确指定目标类型,使用(type)语法进行转换。使用强制类型转换时需要谨慎,以避免数据丢失和精度损失。理解并正确使用这两种类型转换是编写健壮C语言程序的基础。

bsbsjsns的博客 1058

Halcon 形态学 开发案例 (开运算opening(先腐蚀再膨胀)、闭运算closing(先膨胀再腐蚀))

算子方法:功能:使用用户自定义的结构元素对区域进行开运算参数: Region(输入参数) :输入区域 StructElement(输入参数) :结构元素(区域) RegionOpening(输出参数) :开运算后的区域功能:使用圆形结构元素对区域进行开运算参数: Region(输入参数) :输入区域 RegionOpening(输出参数) :开运算后的区域 Radius(输入参数) :圆形结构元素的半径功能:使用矩形结构元素对区域进行开运算。

程序员,他们想的是什么?他们想的永远都是技术,他们崇尚的也永远都是技术。 1618

C语言基础知识笔记——万字学习记录

Hi,大家好,我是半亩花海。本文主要参考浙大翁恺老师的C语言讲解以及其他博主的C语言学习笔记,进而梳理C语言的基础知识,为后续系统性学习数据结构和其他语言等知识夯实一定的基础。

沉思默想,深度学习,半亩星河半亩月,半亩花海半亩云。 2612

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

C语言基础详细学习笔记(小白友好版)

变量就像是一个有名字的容器,可以存储各种类型的数据。名称:如何引用这个变量数据类型:决定它能存储什么样的数据值:实际存储的数据内存地址:数据在计算机内存中的位置返回类型 函数名(参数列表) {// 函数体return 返回值;// 如果返回类型是void,可以省略return// 函数:计算两个整数的和return sum;// 函数:打印一行问候语,无返回值printf("你好,%s!\n", name);// 无需return语句。

weixin_74748597的博客 1298

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

C语言基础笔记(全)

printf函数可以输出各种类型的数据,包括整型、浮点型、字符型、字符串型等,实际原理是printf函数将这些类型的数据格式化为字符串后,放入标准缓冲区,然后将结果显示到屏幕上printf函数根据format给出的格式打印输出到stdout(标准输出)和其他参数中代码格式%c字符%d带符号整数%f浮点数%s一串字符%u无符号整数%x无符号十六进制数,用小写字母%X无符号十六进制数,用大写字母%p一个指针%%一个'%'符号。

señoritaw的博客 1万+

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

c语言基础笔记DAY5_指针基础

c语言基础笔记DAY5 1.内存 每启动一个程序,系统在内存上给该程序分配32位内存空间 4G 内存是由一个一个字节组成,每个字节都会有地址编号 32位系统,内存地址由0x 0000 0000 ~ 0xffff ffff 注意 : 这里的内存地址是逻辑地址空间,虚拟地址. 实际硬件上,虚拟地址会映射到物理内存 2.内存的编号 地址:内存的编号 我们把这个编号(地址)也叫做指针 3.指针大小 不管什么类型的指针,大小只和编译器有关(32位,64位) 32位编译器,指针大小都为四个字节 4.c

GodCaptain的博客 230

C语言基础:第12天笔记

函数 变量的作用域 变量的生命周期 指针

qq_63504030的博客 844

C语言基础 学习笔记总结Day06

1、写一个简单的单向链表。2、自己写一个动态扩容。

qq_62948761的博客 166

C语言基础笔记整理(附代码示例)

C语言基础笔记整理(附代码示例)

weixin_66055196的博客 528

C语言基础 学习笔记总结Day02

条件运算符?C语言中 唯一一个三目运算符- 负号 单目运算符 1 个操作数 -1+ 加号 双目运算符 2 个操作数 1+1格式:条件?语句1 : 语句2当条件为真时 则执行 语句1当条件为假时 则执行 语句2。

qq_62948761的博客 228
上一篇: 图书管理系统
下一篇: c语言实现顺序表和链表(利用了c++的引用)
change_topic
博客等级 码龄4年 97粉丝 41原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值