C语言的深度剖析
文章平均质量分 73
这个专栏是对C语言关键字、符号、预处理、指针和数组、内存管理等进行更深入的剖析和理解。
今天也要写bug、
编程三问:xx是什么?为什么要有xx?xx是怎么实现的?
展开
-
C语言中四种取整方式、取余/取模的运算以及负数取模的问题
零向取整、地板取整、天花板取整、四舍五入取整如果将一个浮点数赋值给整形,只会保存整数位:这种取整方式为零向取整,C语言默认采用的是这种方式C语言中也有对应的零向取整函数:同理还有一种函数是地板取整:它的取整方案是向负无穷大取整:有地板取整,当然也有天花板取整:它的取整方式是向正无穷大取整:最后,还有四舍五入取整的函数:取模/取余取模概念: 如果a和d是两个自然数,d非零,可以证明存在两个唯一的整数 q 和 r,满足 a = q*d + r 且0 ≤ r <原创 2021-09-03 21:45:21 · 11811 阅读 · 11 评论 -
C语言中typedef关键字
与define定义宏不同,typedef这个关键字的本质是做类型重命名,由使用者自己定义一个新的类型。所以我们可以自己定义新的类型:#include<stdio.h>typedef unsigned int u_int;typedef int* int_p;typedef int a[10];//a是一种数组类型typedef struct stu { char name[20]; int age;}stu_t;int main(){ u_int x = 0; int_原创 2021-08-31 10:06:15 · 3346 阅读 · 8 评论 -
C语言中的注释和注意事项
注释在预编译阶段就会被删除掉,但是这里的删除并不是字面意义的删除,而是被替换,注释被替换,本质是替换成空格。以下面的代码为例:#include <stdio.h> int main() { int /* */ i; //正确 char *s = "abcdefgh //hijklmn"; //正确 //Is it a\ valid comment? //正确 in/* */t j; //报错 return 0; }由于被替换成了空格,所以in t j这句话是无法原创 2021-08-31 08:36:09 · 1271 阅读 · 1 评论 -
C语言中volatile关键字
volatile关键字是C语言中非常冷门的关键字,因为用到这个关键字的场景并不多。当不用这个关键字的时候,CPU可能会对我们的代码做一定的优化:内存中的数据要放入CPU中进行运算或控制,而这个数据的值是被放入寄存器中,然后再将寄存器中的数据进行运算或控制的,对于一个死循环int flag=1;while(flag);来说;如果进行优化,则下次循环则不需要再次将flag内存中的值放入寄存器中,而是直接使用寄存器中已有的值进行循环;如果不进行优化,则下次还需要将flag内存中的值放入寄存器中,然后使用寄存器原创 2021-08-29 21:26:15 · 1283 阅读 · 13 评论 -
C语言中return返回函数局部变量的问题
在计算机中,释放空间并不需要将空间中的内容全部置成0或者1,而是只要设置这一块空间的数据无效即可。比如在下载文件时需要花很长时间,但是删除文件却只要几秒钟,这是因为操作系统只是把文件标识(文件头链接)删掉了,文件原文还保留着,我们没了文件标识就找不到这个文件了。所以删除后的文件,还可以用特殊的办法被找回来。这也就意味着,当函数结束调用的时候,函数中的局部变量实际上还是在的,只是函数原来的空间还给编译器(释放)了,也就是说函数中的局部变量是可以被编译器修改的。虽然函数结束后空间还给了编译器,但是我们依然可原创 2021-08-29 16:05:43 · 2321 阅读 · 18 评论 -
C语言中的0 ‘\0‘ ‘0‘ NULL以及类型转化
文章目录0 '\0' '0' NULL真实的类型转化和强制类型0 ‘\0’ ‘0’ NULL0 '\0' NULL都是三种0值,它们在数字上是完全一样的,而且在内存中存的都是二进制0。所以,它们的值是一样的,只不过表现的形式不一样,也就是它们的类型是不同的:0在整形中表示数字0,在字符中’0’表示一个字符它的ASCII码值为48,'\0’是一个字符,表示字符串结束,在ASCII中的值为0NULL 即空指针,它表示一个指针指向地址为0的空间,可以看到这里的0被强制转化为void*指针,这也就意原创 2021-08-28 14:58:49 · 1527 阅读 · 8 评论 -
通过两道书上的题目来加深对指针变量和普通变量的理解
特别声明:这篇博客所涉及到的代码均在VS2019编译器下运行,在其他编译器下可能会报错。最近看了书上两道题目彻底给我整无语了,完全就是误导人,各位记得避雷。不过这两道题目确实挺有意思的,有一道题目还能在VS2019编译器下运行起来。用指针变量来实现两个数取大的数完整的代码是这样的:#include<stdio.h>int* max(int* x, int* y){ if (*x > * y) { return x; } else { return y;原创 2021-08-18 06:08:35 · 243 阅读 · 3 评论 -
数据在内存中存储和取出的一些问题以及float和double型变量的精度损失问题
首先用一段代码来引出这篇文章的问题#include<stdio.h>int main(){ char a=128; char b = 'a'; char c = a + b; int d = 4193; printf("%d\n", a); printf("%d\n", a); printf("%d\n", b); printf("%d\n", c); printf("%c\n", d);}文章目录变量是什么,为什么需要变量为什么scanf要加&,而p原创 2021-08-11 13:31:36 · 467 阅读 · 1 评论 -
C语言中的bool变量
在一些高级语言当中,为了能够完成更好的逻辑判断,因此就有了bool类型,bool类型的变量值只有true和false两种。而在C语言中,一般认为0为假,非0为真。这是因为c99之前,c90是没有bool类型的的。但是c99引入了_Bool类型(_Bool就是一个类型,不过在新增头文件stdbool.h中,被重新用宏写成了 bool,为了保证C/C++兼容性)。目前为止大部分C语言书籍采用的标准还是c90标准,因此我们很少用bool类型。bool类型变量的大小可以看到,这里的bool类型的大小和我原创 2021-08-25 21:24:55 · 6415 阅读 · 5 评论 -
C语言中数据的存储
signed为有符号类型,unsigned为无符号类型,一般signed默认省略。文章目录一、整形在内存的存储1.1.原反补码1.2.将负数赋值给无符号数1.3.char类型截断问题和整形提升问题二、大小端的问题一、整形在内存的存储1.1.原反补码原反补码的概念在博客数据在内存中的存储中提到过,这里再回顾一下:有符号数对于有符号数,一定要能表示该数据是正数还是负数。所以我们一般用最高比特位来进行充当符号位。计算机中的有符号数有三种表示方法,即原码、反码和补码。三种表示方法均有符号位和原创 2021-08-23 14:17:57 · 328 阅读 · 8 评论 -
C语言的数据类型和sizeof关键字
文章目录基本数据类型sizeofsizeof可以求自定义类型大小基本数据类型在变量那一章已经说过,定义变量的本质是当程序加载到内存时,在内存中开辟一块空间用来保存数据。而语法决定,定义变量是需要类型的,这个类型就决定了变量开辟空间的大小。为什么要有类型呢?C语言的类型本质上是对内存进行合理划分,各个变量按需索取。而C语言中有多种类型的原因是应用场景不同,因此解决应用场景对应的计算方式也不同,需要空间的大小也是不同的。其本质是用最小的成本解决各种多样化的场景问题。比如对于一个人的年龄,由于年原创 2021-08-22 22:30:55 · 238 阅读 · 3 评论 -
C语言关键字---static
文章目录一、函数和变量的多文件问题1.1.为什么全局变量和函数需要跨文件访问二、static修饰变量和函数2.1.static修饰全局变量2.2.static修饰局部变量2.3.为什么局部变量具有临时性,全局变量具有全局性一、函数和变量的多文件问题.h: 头文件,一般包含函数声明,变量声明,宏定义,头文件等内容(header).c : 源文件,一般包含函数实现,变量定义等 (.c:c语言)如果在一个源文件定义一个函数,然后再另一个源文件调用,这样的方式可行吗?答案是可行的,但是在生原创 2021-08-22 17:43:32 · 1454 阅读 · 16 评论 -
C语言关键字---register
CPU主要是负责进行计算的硬件单元,但是为了方便运算,一般第一步需要先把数据从内存读取到CPU内,那么也就需要CPU具有一定的数据临时存储能力。注意:CPU并不是当前要计算了,才把特定数据读到CPU里面,那样太慢了。所以现代CPU内,都集成了一组叫做寄存器的硬件,用来做临时数据的保存。文章目录存储金字塔register修饰变量存储金字塔所以离CPU越近,读取速度越快。因此寄存器存在的原因:在硬件层面上,提高计算机的运算效率。因为不需要从内存里读取数据啦。register修饰变量.原创 2021-08-21 23:49:41 · 615 阅读 · 3 评论 -
C语言关键字---auto
在C语言中,使用 auto 修饰的变量,是具有自动存储器的局部变量。在一般情况下,局部变量都是被默认是autoC++中auto的使用和C语言有一些区别,这里仅讨论C语言。文章目录变量的分类变量的作用域变量的生命周期作用域和生命周期的区别auto关键字变量的分类变量的分类在此再说一下:局部变量:包含在代码块中的变量叫做局部变量。局部变量具有临时性。进入代码块,自动形成局部变量,退出代码块自动 释放。全局变量:在所有函数外定义的变量,叫做全局变量。全局变量具有全局性。代码块:用{}括起来的原创 2021-08-21 23:15:07 · 3848 阅读 · 0 评论 -
C语言变量的定义与声明,为什么全局变量不能赋值
文章目录一、对C语言程序的一些补充二、定义域声明2.1.什么是变量2.2.如何定义变量2.3.为什么要定义变量2.4.定义变量的本质2.5.变量声明的本质2.6.定义和生命的区别一、对C语言程序的一些补充对于一个代码:#include<stdio.h>#include <windows.h>int main(){ printf("hello world!\n"); system("pause"); return 0;}我们在编译运行的时候 会将这一段文本代码原创 2021-08-21 22:29:50 · 8167 阅读 · 5 评论