C语言学习专栏(1):易忘点

C语言学习专栏(1):易忘点,第1张

C语言学习专栏(1):易忘点

C语言学习专栏系列:

【版权申明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权);

本博客的内容来自于:C语言学习专栏(1):易忘点;

学习、合作与交流联系q384660495;

本博客的内容仅供学习与参考,并非营利;


include< > 与 #include ""的区别:
    < > 表示系统直接按系统指定的目录检索;“” 表示系统先在 “” 指定的路径(没写路径代表当前路径)查找头文件,如
    果找不到,再按系统指定的目录检索;
main函数
    一个完整的 C 语言程序,是由一个、且只能有一个 main()函数(又称主函数,必须有)和若干个其他函数结合而成(可选)。main 函数是 C 语言程序的入口,程序是从 main 函数开始执行。
C语言编译过程
    预处理:宏定义展开、头文件展开、条件编译等,同时将代码中的注释删除,这里并不会检查语法 ;编译:检查语法,将预处理后文件编译生成汇编文件;汇编:将汇编文件生成目标文件(二进制文件);链接:C 语言写的程序是需要依赖各种库的,所以编译之后还需要把库链接到最终的可执行程序中去;

静态库与动态库
    静态库与动态库都是链接阶段的步骤。静态库(.a、.lib)和动态库(.so、.dll)。静态库编译期间打包到可执行文件中,而动态库是执行时才被载入。动态库规避了空间浪费和静态库在更新、部署和发布带来的麻烦。不同程序调用相同的动态库,内存中只需要保存一份实例。静态库和动态库的最大区别,静态情况下,把库直接加载到程序中,而动态库链接的时候,它只是保留接口,将动态库与程序代码独立,这样就可以提高代码的可复用度,和降低程序的耦合度。动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在。静态库在程序编译时被连接,运行时不再需要。
声明与定义

一般的情况下,把建立存储空间的声明称之为“定义”,而把不需要建立存储 空间的声明称之为“声明”。直接为声明赋值会报错。

原码、反码与补码

在计算机系统中,数值一律用补码来存储,主要原因是:

    统一了零的编码将符号位和其它位统一处理将减法运算转变为加法运算
赋值表达式的返回值

注意,赋值表达式有返回值,等于等号右边的值。变量y的值就是赋值表达式(x = 2 * x)的返回值2。赋值变量符是从右向左执行。

除法注意事项
    C 语言里面的整数除法是整除,只会返回整数部分,丢弃小数部分。如果希望得到浮点数的结果,两个运算数必须至少有一个浮点数,这时 C 语言就会进行浮点数除法。
连续运算符
i < j < k

上面示例中,连续使用两个小于运算符。这是合法表达式,不会报错,但是通常达不到想要的结果,即不是保证变量j的值在i和k之间。因为表示运算符是从左到右计算,所以实际执行的是下面的表达式。

(i < j) < k

python是可以这样判断的

浮点数判断大小

注意,由于存在精度限制,浮点数只是一个近似值,它的计算是不精确的,比如 C 语言里面0.1 + 0.2并不等于0.3,而是有一个很小的误差。

bool类型

C99 标准添加了类型_Bool,表示布尔值。但是,这个类型其实只是整数类型的别名,还是使用0表示伪,1表示真。

字面值的类型

一般情况下,十进制整数字面量(比如123)会被编译器指定为int类型。如果一个数值比较大,超出了int能够表示的范围,编译器会将其指定为long int。如果数值超过了long int,会被指定为unsigned long。如果还不够大,就指定为long long或unsigned long long。

溢出

每一种数据类型都有数值范围,如果存放的数值超出了这个范围(小于最小值或大于最大值),需要更多的二进制位存储,就会发生溢出。大于最大值,叫做向上溢出(overflow);小于最小值,叫做向下溢出(underflow)。

一般来说,编译器不会对溢出报错,会正常执行代码,但是会忽略多出来的二进制位,只保留剩下的位,这样往往会得到意想不到的结果。

unsigned int i = 5;
unsigned int j = 7;

if (i - j < 0) // 错误
  printf("negativen");
else
  printf("positiven");

上面示例的运算结果,会输出positive。原因是变量i和j都是 unsigned int 类型,i - j的结果也是这个类型,最小值为0,不可能得到小于0的结果。正确的写法是写成下面这样。

sizeof返回值

sizeof运算符的返回值,C 语言只规定是无符号整数,并没有规定具体的类型,而是留给系统自己去决定,sizeof到底返回什么类型。不同的系统中,返回值的类型有可能是unsigned int,也有可能是unsigned long,甚至是unsigned long long,对应的printf()占位符分别是%u、%lu和%llu。这样不利于程序的可移植性。

C 语言提供了一个解决方法,创造了一个类型别名size_t,用来统一表示sizeof的返回值类型。该别名定义在stddef.h头文件(引入stdio.h时会自动引入)里面,对应当前系统的sizeof的返回值类型,可能是unsigned int,也可能是unsigned long。

C 语言还提供了一个常量SIZE_MAX,表示size_t可以表示的最大整数。所以,size_t能够表示的整数范围为[0, SIZE_MAX]。

printf()有专门的占位符%zd或%zu,用来处理size_t类型的值。

如果当前系统不支持%zd或%zu,可使用%u(unsigned int)或%lu(unsigned long int)代替。

类型转换
    赋值运算符的自动转换

字节宽度较小的整数类型,赋值给字节宽度较大的整数变量时,会发生类型提升,即窄类型自动转为宽类型。

字节宽度较大的类型,赋值给字节宽度较小的变量时,会发生类型降级,自动转为后者的类型。这时可能会发生截值(truncation),系统会自动截去多余的二进制位,导致难以预料的结果。

    运算符的自动转换

不同的浮点数类型混合运算时,宽度较小的类型转为宽度较大的类型,比如float转为double,double转为long double。

不同的整数类型混合运算时,宽度较小的类型会提升为宽度较大的类型。比如short转为int,int转为long等,有时还会将带符号的类型signed转为无符号unsigned。避免无符号与有符号的混合运算,会出现意想不到的错误。

    函数的参数和返回值,会自动转成函数定义里指定的类型。
可移植类型

程序员有时控制准确的字节宽度,这样的话,代码可以有更好的可移植性,头文件stdint.h创造了一些新的类型别名。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5714790.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-18
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存