
C语言基础
文章平均质量分 96
从0开始的C语言学习历程
爱喝兽奶的荒天帝
优快云全栈领域新星创作者,阿里云专家博主。书山有路勤为径,学海无涯苦作舟。自律遇见更好的自己!!!
展开
-
【C/C++基础实战】:用C++实现通讯录管理系统——含完整源码
因此我们可以把检测联系人是否存在封装成一个函数中,如果存在,返回联系人在通讯录中的位置,不存在返回-1。设计时候可以在通讯录结构体中,维护一个容量为1000的存放联系人的数组,并记录当前通讯录中联系人数量。删除联系人前,我们需要先判断用户输入的联系人是否存在,如果存在删除,不存在提示用户没有要删除的联系人。根据用户输入的联系人判断该通讯录中是否有此人,查找到进行删除,并提示删除成功,查不到提示查无此人。思路:判断如果当前通讯录中没有人员,就提示记录为空,人数大于0,显示通讯录中信息。原创 2024-05-02 19:30:42 · 3496 阅读 · 116 评论 -
【感受C++的魅力】:用C++演奏歌曲《起风了》——含完整源码
enum Voice_ = 0XFFX1 至 X7:这些音色从 C2 到 B2,表示较低音区的音符。这些是为了模拟某种低音乐器,如低音吉他或低音萨克斯风。L1 至 L7:这些音色从 C3 到 B3,处于中低音区,代表中音区的乐器,如中提琴或次中音萨克斯风。M1 至 M7:这些音色从 C4 到 B4,处于中央音区,通常用于模拟人声或中等音高的乐器,如小提琴或长笛。H1 至 H7:这些音色从 C5 到 B5,处于较高音区,用于模拟高音乐器,如小号或短笛。LOW_SPEED。原创 2024-04-19 08:11:22 · 11077 阅读 · 164 评论 -
【C语言基础】:预处理详解(二)
在C语言编程中,命令行定义指的是通过编译器的命令行参数来定义宏或者设置编译时的选项。这种方法允许开发者在不修改源代码的情况下,动态地改变编译过程和生成的程序的行为。定义宏大多数C语言编译器允许使用命令行参数来定义宏。在GCC和Clang等编译器中,可以使用 -D 选项来定义宏。【示例】:命令行定义int main()// SZ未定义i < SZ;i++)i < SZ;原创 2024-04-16 02:39:18 · 2040 阅读 · 109 评论 -
【C语言基础】:预处理详解(一)
在C语言中设置了许多的预定义符号,这些预定义符号是可以直接使用的,预定义符号也是在预处理阶段进行处理的。常见的预定义符号__FILE__ //进⾏编译的源文件__LINE__ //文件当前的行号__DATE__ //文件被编译的日期__TIME__ //文件被编译的时间__STDC__ //如果编译器遵循ANSI C,其值为1,否则未定义【示例】int main()return 0;我们在VS上使用会发现显示未定义,这也就说明VS的编译器是不完全遵循ANSI C。原创 2024-04-14 02:59:48 · 2105 阅读 · 94 评论 -
【C语言基础】:编译和链接(计算机中的翻译官)
我们在 test.c 文件中每⼀次使用 Add 函数和 g_val 的时候必须确切的知道 Add 和 g_val 的地址,但是由于每个文件是单独编译的,在编译器编译 test.c 的时候并不知道 Add 函数和 g_val变量的地址,所以暂时把调用 Add 的指令的目标地址和 g_val 的地址搁置。链接是编译过程的最后一个阶段,它负责将编译阶段生成的一个或多个目标文件与所需的库文件合并,生成最终的可执行文件。文件,每个C文件都会生成对应的目标文件,每个源文件都是经过编译器单独处理的。原创 2024-04-11 01:32:54 · 1783 阅读 · 95 评论 -
【C语言基础】:文件操作详解(后篇)
fputc函数原型将字符写入流将一个字符写入流并推进位置指示器。字符被写入流的内部位置指示器所指示的位置,然后自动向前移动一个。参数说明character: 要写入的字符,以整数形式表示。stream:指向要写入的文件的文件指针。函数返回值如果成功写入字符,则返回写入的字符,如果发生错误,则返回 EOF。【示例1】int main()// 打开文件return 1;// 写文件// 关闭文件fclose(pf);pf = NULL;return 0;【示例2】原创 2024-04-09 02:57:49 · 1988 阅读 · 123 评论 -
【C语言基础】:文件操作详解(前篇:准备知识)
文件是指存储在计算机或其他电子设备上的数据集合,通常用来存储文本、图像、音频、视频或其他类型的信息。程序文件和数据文件。原创 2024-04-06 16:14:31 · 1858 阅读 · 102 评论 -
【C语言基础】:动态内存管理(含经典笔试题分析)
Test函数里面str申请了100个字节的空间,将hello拷贝到str所指向的空间中,就直接用free释放掉了,导致str成了野指针,之前将hello拷贝到str中,所以str一定不是空指针,所以下面的if语句一定会执行,打印str空间里的内容会对野指针进行操作导致程序崩溃。:Test函数里面将str进行传址调用,在GetMemory函数里面申请100个字节大小的空间,将hello拷贝到str所指向的空间中,但是使用之后并没有使用free函数进行释放,导致内存泄漏。这样函数返回的是⼀个新的内存地址。原创 2024-04-04 21:33:58 · 1592 阅读 · 78 评论 -
【C语言基础】:自定义类型(二) -->联合和枚举
上述的结构其实设计的很简单,用起来也方便,但是结构的设计中包含了所有礼品的各种属性,这样使得结构体的大小就会偏大,比较浪费内存。,但这个联合体的大小却并不是5个字节的大小,而是8个字节,这说明联合体的大小不全是最大成员的大小。从运行结果来看:这个联合体中有两个成员变量,一个整形和一个字符型,按理说应该是5个字节的大小,但这个联合体的大小却只有4个字节,这也就是联合体的特点了。联合的成员是共用同一块内存空间的,这样⼀个联合变量的大小,至少是最大成员的大小(因为联合体至少得有能力保存最大的那个成员)。原创 2024-04-02 00:18:44 · 1948 阅读 · 111 评论 -
【C语言基础】:自定义类型(一)--> 结构体
在C语言中,有内置类型(也称为基本数据类型)和自定义类型(结构体)两种类型。在C语言中,除了内置的基本数据类型外,还可以通过结构体(Structures)和枚举类型(Enums)来定义自定义类型。结构体(Structures)结构体是一种用户自定义的数据类型,用于组合不同类型的数据成员。它允许将多个不同类型的变量组合在一起,形成一个新的数据类型,以便更方便地操作相关数据。枚举类型(Enums)枚举类型是一种用户自定义的数据类型,用于定义一组相关的命名常量。原创 2024-03-30 13:50:57 · 1900 阅读 · 92 评论 -
【C语言基础】:数据在内存中的存储
在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8个bit位,但是在C语言中除了了8 bit 的 char 之外,还有16 bit 的 short 型,32 bit 的 long 型(要看具体的编译器),另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于⼀个字节,那么必然存在着⼀个如何将多个字节安排的问题。造成这种情况的原因是因为超过一个字节的数据在内存中存储的时候,就有储存顺序的问题,按照不同的存储顺序,我们分为大端字节序存储和小端字节序存储。原创 2024-03-28 23:50:01 · 1760 阅读 · 73 评论 -
【C语言基础】:内存操作函数
一个整型占4个字节,比较前16个字节就是比较前4个元素,前4个元素都是一样的,所以返回0。每访问一个字节后就自增一,拷贝完成后,这时的dest已经不再指向首元素地址,所以在这之前要创建一个void* 的指针记录dest,最后返回记录dest的指针即可。将ptr1所指向的内存块的前num字节与ptr2所指向的前num字节进行比较,如果它们都匹配则返回0,如果不匹配则返回不同于0的值,表示哪个值更大。:将arr1中的1,2,3,4,5这几个元素拷贝到arr1中的3,4,5,6,7的位置。在比较前17个字节。原创 2024-03-25 23:37:14 · 1847 阅读 · 113 评论 -
【C语言基础】:字符串函数(二)
这种情况就比较复杂,当str1中的第一个b和str2中的b匹配时,str2中的第一个和第二个都能匹配上,当第三个str2是c,而str1却是b,这时候又要回去重新进行匹配,但str2中的指针已经指向c了,没办法回去,所以这里不仅需要一个指针记录开始匹配的位置,还需要一个指针指向str2的开始位置,方便那个指针能指向回来。如果它们彼此相等,则继续执行后面的对,直到字符不相同,直到达到终止的空字符,或者直到两个字符串中的num字符匹配,以先发生的为准。比较C字符串str1和C字符串str2的最多num个字符。原创 2024-03-22 06:41:48 · 2744 阅读 · 118 评论 -
【C语言基础】:字符函数和字符串函数
destination中的结束null字符被source的第一个字符覆盖,并且在destination中由两者串联形成的新字符串的末尾包含一个空字符。可以看到,标准里面的返回值是一个大于或小于0的数,但VS的编译器直接定为1和-1,其他编译器可能是返回一个大于0或小于0的数。C语言中有一系列的函数是对字符进行分类的,就是对判断一个字符属于什么类型的字符,这类字符函数的使用都要包含一个头文件。在上面的示例中,我们将小写转大写,是-32完成的效果,有了转换函数,就可以直接使用 tolower 函。原创 2024-03-18 14:48:52 · 2995 阅读 · 115 评论 -
【C语言基础】:深入理解指针(终篇)
回调函数就是⼀个通过函数指针调⽤的函数。如果你把函数的指针(地址)作为参数传递给另⼀个函数,当这个指针被用来调用其所指向的函数时,被调⽤的函数就是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。上面的计算器示例也可以用回调函数实现int x, y;printf("请输入两个操作数:");int main()//转移表doprintf("请选择:");原创 2024-03-10 23:43:42 · 1950 阅读 · 72 评论 -
【C语言基础】:深入理解指针(三)
二维数组传参,形参的部分可以写成数组,也可以写成指针形式。原创 2024-03-08 08:54:12 · 2035 阅读 · 84 评论 -
【C语言基础】:深入理解指针(二)
⼀维数组传参,形参的部分可以写成数组的形式,也可以写成指针的形式。原创 2024-03-05 02:34:29 · 2305 阅读 · 114 评论 -
【C语言基础】:深入理解指针(一)
计算机上CPU( 中央处理器) 在处理数据的时候 ,需要的数据是在内存中读取的 ,处理后的 数据也会放回内存中 ,那我们买电脑的时候 , 电脑上内存是8GB/16GB/32GB等 ,那这些内存空间如何 高效的管理呢?前面的内容我们了解到,32位机器假设有32根地址总线,每根地址线出来的电信号转换成数字信号后是1或者0 ,那我们把32根地址线产生的2进制序列当做一个地址,那么一个地址就是32个bit位,需要4个字节才能存储。首先,必须理解,计算机内是有很多的硬件单元,而硬件单元是要互相协同工作的。原创 2024-02-29 22:42:02 · 2427 阅读 · 102 评论 -
【C语言基础】:操作符详解(二)
上期回顾:【C语言基础】:操作符详解(一)【练习一】:不能创建临时变量(第三个变量), 实现两个整数的交换。方法一:我们可以运用加减法来实现这个功能。分析:下面是代码实现:很明显,这种方法也存在着明显的不足,那就是当a和b的值比较大时,a和b可能会超出int的范围,会出现溢出的现象,导致无法进行值的互换。方法二:按位异或实现上次我们学习了位操作符,其中按位异或就是对应二进制位相同为0,相异为1。根据这个特性,我们也能实现这个功能。分析:下面说代码实现:这种方法也存在着局限性,首先要知道按位操作符原创 2024-02-26 18:32:49 · 3272 阅读 · 118 评论 -
【C语言基础】:操作符详解(一)
通俗来讲二进制、八 进制、 十进制、 十六进制是数值的不同表示形式而已。15的2进制表现形式: 111115的8进制表现形式: 1715的10进制表现形式: 1515的16进制表现形式: F//16进制的数值之前写:0x//8进制的数值之前写:0int main()return 0;原创 2024-02-25 15:52:45 · 2427 阅读 · 43 评论 -
【C语言基础】:函数递归详解
基本情况(Base Case):递归函数必须包含一个或多个基本情况,即能够直接解决的最简单的问题。当函数达到基本情况时,递归将停止。基本情况提供了递归终止的条件。递归调用(Recursive Call):递归函数在解决复杂问题时会调用自身,但每次调用时问题规模会减小,直到达到基本情况。递归调用是递归函数实现的关键,它使得函数能够重复地处理子问题。问题规模减小:递归调用必须保证问题规模在每次递归时都减小,否则递归可能无法终止。通过每次递归调用都将问题规模减小,最终达到基本情况。原创 2024-02-04 20:10:39 · 8036 阅读 · 8 评论 -
【C语言基础】:函数详解
函数的声明指的是在使用函数之前,提前告知编译器函数的名称、参数列表和返回类型。通过函数的声明,编译器可以知道函数的存在,并且能够对函数进行正确的调用。函数的声明通常包含在头文件(.h文件)中,并在需要使用函数的源文件中包含该头文件。函数的定义则是指实际实现函数的代码部分,包括函数体和相应的逻辑。函数的定义通常包含在源文件(.c文件)中,并在需要使用函数的地方进行调用。注意函数的调用一定要满足先声明后使用函数的定义也是一种特殊的声明,所以函数的定义放在调用之前也可以。总结。原创 2024-01-31 13:58:09 · 1372 阅读 · 3 评论 -
【C语言基础】:数组
我们可以通过行和列的下标定位我们想要访问的元素,例如,我们要访问行下标为2,列下标为1的元素,也就是arr[2][1],就能快速定位到4。在上面的示例中,数组arr就是一个变长数组,因为它的长度取决于变量 n 的值,编译器没法事先确定,只有运行时才能知道 n 是多少。在C99标准之前,C语言在创建数组的时候,数组大小的指定只能使用常量、常量表达式,或则在初始化数据时,可以省略数组的大小。利用数组元素类型都相同的原理,先计算一个元素所占的字节个数,就可以计算出数组元素的个数啦。原创 2024-01-27 10:27:01 · 1303 阅读 · 2 评论 -
【C语言基础】:分支与循环
上⾯的代码排版,让 else 和第⼀个 if 语句对齐,让我们以为 else 是和第一个if匹配的,当 if语句不成立的时候,⾃然想到的就是执行 else 子句,打印 haha ,但实际上 else 是和第⼆个 if进行匹配的,这样后边的 if…=0则执行循环语句,循环语句执行完后,再去执行表达式3 ,调整循环变量,然后再去 表达式2 的地方执行判断,表达式2 的结果是否为0,决定循环是否继续。输入负数则会打印这是一个负数。,也就是表达式的结果如果是0,则语句不执行,表达式的结果如果不是0,则语句执行。原创 2024-01-25 11:02:15 · 1368 阅读 · 2 评论