![](https://img-blog.csdnimg.cn/20201014180756927.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
C语言学习1
文章平均质量分 93
学习C语言的学习博客
流星白龙
https://gitee.com/yudukai(Gitee链接)
展开
-
【C语言】19.预处理详解
C语言设置了一些预定义符号,可以直接使用,预定义符号也是在预处理期间处理的。__FILE__ //进行编译的源文件__LINE__ //文件当前的行号__DATE__ //文件被编译的日期__TIME__ //文件被编译的时间__STDC__ //如果编译器遵循ANSI C,其值为1,否则未定义这行代码会报错,说明VS没有完全遵循ANSIC这个标准return 0;return 0;原创 2024-07-02 00:51:29 · 1305 阅读 · 1 评论 -
【C语言】18.编译和链接
编译器所能做的分析是语义的静态分析。在独立的环境中,程序的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成。等待最后链接的时候由链接器根据引用的符号 Add 在其他模块中查找 Add 函数的地址,然后将。其实翻译环境是由编译和链接两个大的过程组成的,而编译又可以分解成:预处理(有些书也叫预编译)、编译、汇编三个过程。编译过程就是将预处理后的文件进行一系列的:词法分析、语法分析、语义分析及优化,生成相应的汇编代码文件。)内存,存储于静态内存中的变量在程序的整个执行过程一直保留他们的值。原创 2024-06-27 00:00:49 · 863 阅读 · 0 评论 -
【C语言】17.文件操作
磁盘(硬盘)上的文件是文件。程序文件数据文件(从文件功能的角度来分类的)。函数名功能适用于fgetc(读字符)字符输入函数所有输入流fputc(写字符)字符输出函数所有输出流fgets(读字符串)文本行输入函数所有输入流fputs(写字符串)文本行输出函数所有输出流fscanf格式化输入函数所有输入流fprintf格式化输出函数所有输出流fread二进制输入所有输入流fwrite二进制输出所有输出流上面说的适用于所有输入流一般指适用于标准输入流和其他输入流(如文件输入流);原创 2024-06-24 22:41:24 · 1408 阅读 · 0 评论 -
【C语言】16.动态内存管理
栈区(stack):在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。栈区主要存放运行函数而分配的局部变量函数参数返回数据返回地址等。《函数栈帧的创建和销毁》堆区(heap):一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收。分配方式类似于链表。数据段(静态区):(static)存放全局变量静态数据。程序结束后由系统释放。代码段:存放函数体(类成员函数和全局函数。原创 2024-06-21 22:23:15 · 1414 阅读 · 0 评论 -
【C语言】15.联合和枚举
上述的结构其实设计的很简单,用起来也方便,但是结构的设计中包含了所有礼品的各种属性,这样使得结构体的大小就会偏大,比较浪费内存。所以我们就可以把公共属性单独写出来,剩余属于各种商品本身的属性使用联合体起来,这样就可以介绍所需的内存空间,一定程度上节省了内存。联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)。当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。的整数倍,要对齐到最大对齐数的整数倍,也就是。原创 2024-06-18 00:34:41 · 731 阅读 · 0 评论 -
【C语言】14.自定义类型:结构体
位段的声明和结构是类似的,有两个不同:位段的成员必须是int或signed int,在C99中位段成员的类型也可以选择其他类型。位段的成员名后边有一个冒号和一个数字。int _b : 5;位段中的位,指的是二进制位(bit位)。int _a : 2;就是a占2个bit位。int _b : 5;就是b占5个bit位。那我们可以把这个位段写成这样吗?答案是:不可以。一个整型4个字节,32个bit位。50直接超了。为什么会出现位段呢?比如:如果_a。原创 2024-06-17 00:39:46 · 952 阅读 · 0 评论 -
【C语言】13.数据在内存中的存储
大端(存储)模式:是指数据的低位字节内容保存在内存的高地址处,而数据的高位字节内容,保存在内存的低地址处。小端(存储)模式:是指数据的低位字节内容保存在内存的低地址处,而数据的高位字节内容,保存在内存的高地址处。原创 2024-06-13 01:44:59 · 1118 阅读 · 0 评论 -
【C语言】12.C语言内存函数
memcpy:内存拷贝memmove:内存移动memset:内存设置memcmp:内存比较。原创 2024-06-11 23:24:31 · 1034 阅读 · 0 评论 -
【C语言】11.字符函数和字符串函数
是0,表示没有错误,当我们在使用标准库中的函数的时候发生了某种错误,就会将对应的错误码,存放在。通过返回值来说明是否是小写字母,如果是小写字母就返回非0的整数,如果不是小写字母,则返回0。中,而一个错误码的数字是整数很难理解是什么意思,所以每一个错误码都是有对应的错误信息的。C语言中有一系列的函数是专门做字符分类的,也就是一个字符是属于什么类型的字符的。个字母,如果提前发现不一样,就提前结束,大的字符所在的字符串大于另外一个。函数打印完参数部分的字符串后,再打印一个冒号和一个空格,再打印错误信息。原创 2024-06-10 22:35:25 · 1236 阅读 · 0 评论 -
【C语言】10.C语言指针(5)
因为我编译的环境是x64,所以是8,如果是x86的环境下编译,那么就是4。因为我编译的环境是x64,所以是8,如果是x86的环境下编译,那么就是4。因为我编译的环境是x64,所以是8,如果是x86的环境下编译,那么就是4。是对一个数组的地址的解引用,访问的是一个数组。因为我编译的环境是x64,所以是8,如果是x86的环境下编译,那么就是4。因为我编译的环境是x64,所以是8,如果是x86的环境下编译,那么就是4。因为我编译的环境是x64,所以是8,如果是x86的环境下编译,那么就是4。原创 2024-06-08 20:09:58 · 926 阅读 · 0 评论 -
【C语言】10.C语言指针(4)
如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,被调用的函数就是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。这个程序排序整型数据是没问题的,但是能排序字符数组吗?:base指向的数组元素中一个元素的大小,单位是字节。回调函数就是一个通过函数指针调用的函数。函数进行比较,那么谁就来提供比较函数。:指向待排序数组的第一个元素的指针。这个函数是用来对数据进行排序的,原创 2024-06-02 02:17:44 · 1149 阅读 · 0 评论 -
【C语言】10.C语言指针(3)
那就意味着二维数组传参本质上也是传递了地址,传递的是第一行这个一维数组的地址,那么形参也是可以写成指针形式的。这段代码的意思是调用0地址处的那个函数,0地址处放的那个函数是无参,返回类型是void。数组指针变量是用来存放数组地址的,那怎么获得数组的地址呢?函数指针变量应该是用来存放函数地址的,未来通过地址能够调用函数的。所以,二维数组的数组名表示的就是第一行的地址,是一维数组的地址。有了数组指针的理解,我们就能够讲一下二维数组传参的本质了。都是用来传参的,只不过一个有参数,一个没有参数。原创 2024-06-01 15:34:06 · 1168 阅读 · 0 评论 -
【C语言】10.C语言指针(2)
这里我们发现&arr[0]和&arr[0]+1相差4个字节,arr和arr+1 相差4个字节,是因为&arr[0] 和 arr 都是首元素的地址,+1就是跳过一个元素。,数组元素的访问在编译器处理的时候,也是转换成首元素的地址+偏移量求出元素的地址,然后解引用来访问的。:这里的数组名表示整个数组,取出的是整个数组的地址(整个数组的地址和数组首元素的地址是有区别的)这步做完后,最后的元素会是最大的数。:sizeof中单独放数组名,这里的数组名表示整个数组,计算的是整个数组的大小,单位是字节。原创 2024-05-27 23:23:33 · 1553 阅读 · 0 评论 -
【C语言】10.C语言指针(1)
32位机器假设有32根地址总线,每根地址线出来的电信号转换成数字信号后是1或者0,那我们把32根地址线产生的2进制序列当做一个地址,那么一个地址就是32个bit位,需要4个字节才能存储。同理64位机器,假设有64根地址线,一个地址就是64个二进制位组成的二进制序列,存储起来就需要8个字节的空间,指针变量的大小就是8个字节。如果p拿到n的地址就能修改n,这样就打破了const的限制,这是不合理的,所以应该让p拿到n的地址也不能修改n,那接下来怎么做呢?),这种类型的指针可以用来接受任意类型地址。原创 2024-05-26 21:25:08 · 1113 阅读 · 0 评论 -
【C语言】8.C语言操作符详解(3)
即使有了操作符的优先级和结合性,我们写出的表达式依然有可能不能通过操作符的属性确定唯一的计算路径,那这个表达式就是存在潜在风险的,建议不要写出特别复杂的表达式。原创 2024-05-25 00:30:54 · 1215 阅读 · 0 评论 -
【C语言】8.C语言操作符详解(2)
/学生类型//成员变量int age;//全局变量int a;//局部变量//这个s1就是用Student这个学生类型创建的对象。return 0;//学生类型//成员变量int age;//全局变量//这里面的s4, s5 ,s6和上面的s3一个意思,就是写法不同//学生类型//成员变量int age;}s4 = { "小李",22,22.2 }, s5, s6;//全局变量struct Student s3 = { "王五",25,88.8 };原创 2024-05-24 01:17:12 · 699 阅读 · 0 评论 -
【C语言】8.C语言操作符详解(1)
从这三次变化里面我们可以看到,我们执行了一次n=n&(n-1),那么n最右面那个1就会消失。有符号整数的三种表示方法均有符号位和数值位两部分,2进制序列中,最高位的1位是被当做符号位,剩余的都是数值位。上面这个方法有点问题,如果a+b的和超过了一个整型数据的存储大小,那么就计算不了了。这里就不过多赘述了。算术右移:左边用原该值的符号位填充(正数左边补0,负数左边补1),右边丢弃。不论-1的补码前面多少个1,只要和1按位与后就只看最后一位是不是1。反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。原创 2024-05-24 01:15:48 · 772 阅读 · 0 评论 -
【C语言】9.C语言函数栈帧的创建和销毁
当我们调用完函数后,弹出ebp,和call指令下一条指令的地址后,esp指针往下走的时候就可以跳转到call指令下一条指令的地址。,也就是上面说的call指令的下一条指令的地址。ret指令返回的时候其实就是在栈顶返回了call指令的下一条指令的地址。这样才能返回之前的地方。就是靠的寄存器传递的,放到这样一个全局的寄存器里面就安全了。这个空间是为main函数开辟的,那么我们就称这个空间是为main函数开辟的一块函数栈帧。ebp出栈了之后,这个ebp指针指向了下面,因为这个出栈的ebp是为main函数创建的。原创 2024-05-23 01:42:01 · 1120 阅读 · 0 评论 -
【C语言】7.C语言函数递归
例如在栈区分配内存空间的时候,先给main一个空间,然后调用Fact,给他一个橙色空间,然后调用Fact,给他一个紫色空间,然后调用Fact,给他一个绿色空间,然后调用Fact,给他一个红色空间,然后调用Fact,给他一个棕色空间,然后调用Fact,给他一个青色空间。所以递归的思考方式就是把大事化小的过程。斐波那契数列:1,1,2,3,5,8,13,21,34,55,89……因为递归程序会不断的展开,在展开的过程中,我们很容易就能发现,在递归的过程中会有重复计算,而且递归层次越深,冗余计算就会越多。原创 2024-05-16 21:34:57 · 1873 阅读 · 0 评论 -
【C语言】6.C语言VS实用调试技巧(2)
编译型错误一般都是语法错误,这类错误一般看错误信息就能找到一些蛛丝马迹的,双击错误信息也能初步的跳转到代码错误的地方或者附近。编译错误,随着语言的熟练掌握,会越来越少,也容易解决。我们打开监视,这个很奇怪吧,因为我们定义arr数组里面最多10个元素,现在却出现了arr[12],而且还有值。在VS上切换到X64,这个使用的顺序就是相反的,在Release版本的程序中,这个使用的顺序也是相反的。运行时错误,是千变万化的,需要借助调试,逐步定位问题,调试解决的是运行时问题。,但这里是15,说明有问题。原创 2024-05-15 21:28:33 · 272 阅读 · 0 评论 -
【C语言】6.C语言VS实用调试技巧(1)
bug现在一般是指在电脑系统或程序中,隐藏着的一些未被发现的缺陷或问题,简称程序漏洞。当我们发现程序中存在的问题的时候,那下一步就是找到问题,并修复问题。这个找问题的过程叫称为调试,英文叫debug。调试一个程序,首先是承认出现了问题,然后通过各种手段去定位问题的位置,可能是逐过程的调试,也可能是隔离和屏蔽代码的方式,找到问题所的位置,然后确定错误产生的原因,再修复代码,重新测试。原创 2024-05-15 21:23:06 · 740 阅读 · 0 评论 -
【C语言】5.C语言函数(2)
C语言编译器对源代码进行编译的时候,从第一行往下扫描的,所以函数调用之前先声明一下调用的函数。menu();return 0;3-5行是函数menu的定义,第8行是函数的调用。menu();return 0;如果把函数定义放在函数调用的后面就会报错。menu();return 0;这里的函数定义放在了函数调用的后面,但是第3行是函数声明,所以就不会报错。函数的调用一定要满足,先声明后使用;函数的定义也是一种特殊的声明,所以如果函数定义放在调用之前也是可以的。原创 2024-05-15 21:13:00 · 1003 阅读 · 0 评论 -
【C语言】5.C语言函数(1)
ret_type fun_name(形式参数) {ret_type 是函数返回类型,例如voidint等等。fun_name 是函数名,函数有了名字方便调用,所以函数名尽量要根据函数的功能起的有意义。括号中放的是形式参数,函数的参数也可以是 void ,明确表示函数没有参数。如果有参数,要交代清楚参数的类型和名字,以及参数个数。{}括起来的是函数体,函数体就是完成计算的过程。原创 2024-05-15 21:10:05 · 583 阅读 · 0 评论 -
【C语言】4.C语言数组(2)
在C99标准之前,C语言在创建数组的时候,数组大小的指定只能使用常量、常量表达式,或者如果我们初始化数据的话,可以省略数组大小。这个例子里面,数组 arr 就是变长数组,因为它的长度取决于变量 n 的值,编译器没法事先确定,只有运行时才能知道 n 是多少。这样的语法限制,让我们创建数组就不够灵活,有时候数组大了浪费空间,有时候数组又小了不够用。于是,C99标准中给一个变长数组的新特性,允许我们可以使用变量指定数组大小。从输出的结果来看,每一行内部的每个元素都是相邻的,地址之间相差4个字节。原创 2024-05-15 00:52:30 · 700 阅读 · 0 评论 -
【C语言】strcmp函数讲解
它从两个字符串的第一个字符开始比较,如果相同则继续比较下一个字符,直到找到不同的字符或者到达字符串的结尾。在这里,strcmp是先比较两个数组第一个元素 ,发现一样继续比较;在这里,strcmp是先比较两个数组第一个元素 ,发现一样继续比较;在这里,strcmp是先比较两个数组第一个元素 ,发现一样继续比较;在这里,strcmp是先比较两个数组第一个元素 ,发现一样继续比较;函数不是简单比较两个数组元素数量的函数,而是按位比较数组元素,根据两数组对应元素出现的第一组变化来比较。头文件中,因此在使用。原创 2024-05-11 22:18:02 · 1088 阅读 · 0 评论 -
【C语言】4.C语言数组(1)
a[0]就是a数组里第一个元素1,a[1]就是a数组里第二个元素2,a[2]就是a数组里第三个元素3,a[3]就是a数组里第四个元素4,a[4]就是a数组里第五个元素5。从输出的结果我们分析,数组随着下标依次的增长,地址也由小到大变化,并且每两个相邻的元素之间相差4(因为一个整型是4个字节).这五个元素分别是:a[0],a[1],a[2],a[3],a[4]因为不是所有数组里每个元素都是4字节的,这里我们只举了整型的例子。因为不是所有数组里每个元素都是4字节的,这里我们只举了整型的例子。原创 2024-05-11 15:07:48 · 1074 阅读 · 1 评论 -
【C语言】3.C语言分支和循环(2)
do.while 语句中的 break 和 continue 的作用和 while 循环中几乎一模一样,这里就不过多展示了。定义了变量j的值为0,和变量flag的值为1(如果经历了循环后,flag的值还为1,那么i就是素数)表达式为真,就会进行下一次,表达式为假,则不再继续循环。while 和 for 都是先判断,条件如果满足就进入循环,执行循环语句,如果不满足就跳出循环;之后,a的值为11,重新进入while循环的语句判断,发现。后,就会跳出本次循环,while语句继续判断a是否为真。原创 2024-05-09 19:52:34 · 1003 阅读 · 0 评论 -
【C语言】3.C语言分支和循环(1)
例如:score>=90优秀,70原创 2024-05-08 22:56:14 · 1009 阅读 · 2 评论 -
【C语言】2.C语言数据类型和变量(下)
printf() 的作用是将参数文本输出到屏幕。return 0;printf() 不会在行尾自动添加换行符,运行结束后,光标就停留在输出结束的地方,不会自动换行。为了让光标移到下一行的开头,可以在输出文本的结尾,添加一个换行符\n。return 0;原创 2024-05-07 22:01:10 · 680 阅读 · 0 评论 -
【C语言】2.C语言数据类型和变量(上)
C语言使用整型类型来描述整数,使用字符类型来描述字符,使用浮点型类型来描述小数。原创 2024-05-07 00:39:59 · 913 阅读 · 0 评论 -
【C语言】1.C语言常见概念
为了不再重复实现常见的代码,让程序员提升开发效率,C语言标准规定了一组函数,这些函数再由不同的编译器厂商根据标准进行实现,提供给程序员使用。这些函数组成了一个函数库,被称为标准库,这些函数也被称为库函数。一个系列的库函数一般会声明在同一个头文件中,所以库函数的使用,要包含对应的头文件。关键字都有特殊的意义,是保留给C语言使用的程序员自己在创建标识符的时候是不能和关键字重复的关键字也是不能自己创建的。原创 2024-05-06 18:29:36 · 1005 阅读 · 0 评论