【WIP】C 语言拾遗 Part.1

long 与 long long

long 一般占用 4~8 字节,long long 至少 占用 8 个字节。不同的平台和编译器,长度可能不同。

sizeof() 运算符

注意 sizeof() 属于运算符的一种,这个运算符用于测量括号内的变量(或类型)占用的字节数量。多数情况下,这一数量在编译时确定,因此 sizeof() 的运行结果是一个编译时常量。但也有例外,如 C99 标准引入的变长数组特性。该类数组的 size 需在程序运行时、数组开辟后确定。

由于是编译时常量,括号内如果是表达式,则表达式不会被执行。

1
2
3
int a = 1; // a = 1
int b = sizeof(a++); // b = 4
// a = 1, a++ 没有执行

浮点数精度问题

老生长谈的话题了。由于误差,以下的逻辑判断结果都是成立(1):

1
2
(0.1 + 0.1 + 0.1) != 0.3; // 1;
1 + (1e123 - 1e123) != (1 + 1e123) - 1e123; // 1;

没有 body 的 for 循环

可以写成如下形式:

1
2
3
for(i = 0; i < 10; i++) {
;
}

或者如下形式:

1
for(i = 0; i < 10; i++);

三目运算符

1
a ? b : c

等价于

1
2
3
4
5
6
if(a){
b;
}
else{
c;
}

这没什么可说的。

面条式代码

面条式代码(Spaghetti code)最初指代码过度使用 goto 等破坏程序结构化(顺序结构、选择结构、循环结构)的关键字的代码。现也泛指不满足项目代码规范的代码、缺乏代码风格的代码、项目要求经常变化导致过度冗余的代码或缺乏项目编程经验者写出的代码。

limits.h

C 语言标准库之一,包含了常见数据类型的数据上界和数据下界。节选代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/* Maximum value an `unsigned char' can hold.  (Minimum is 0).  */
#undef UCHAR_MAX
#define UCHAR_MAX 255

/* Minimum and maximum values a `char' can hold. */
#ifdef __CHAR_UNSIGNED__
#undef CHAR_MIN
#define CHAR_MIN 0
#undef CHAR_MAX
#define CHAR_MAX 255
#else
#undef CHAR_MIN
#define CHAR_MIN (-128)
#undef CHAR_MAX
#define CHAR_MAX 127
#endif

/* Minimum and maximum values a `signed short int' can hold. */
#undef SHRT_MIN
#define SHRT_MIN (-32768)
#undef SHRT_MAX
#define SHRT_MAX 32767

/* Maximum value an `unsigned short int' can hold. (Minimum is 0). */
#undef USHRT_MAX
#define USHRT_MAX 65535

/* Minimum and maximum values a `signed int' can hold. */
#ifndef __INT_MAX__
#define __INT_MAX__ 2147483647
#endif
#undef INT_MIN
#define INT_MIN (-INT_MAX-1)
#undef INT_MAX
#define INT_MAX __INT_MAX__

/* Maximum value an `unsigned int' can hold. (Minimum is 0). */
#undef UINT_MAX
#define UINT_MAX (INT_MAX * 2U + 1)

十六进制和 printf

十六进制可以直接用于赋值。比如下列语句可将 a 赋值为 1:

1
int a = 0x01;

要注意 printf 在进行格式化输出的时候,floatdouble 类型都可以用 %f,而dobule 类型也可以用 %lflong double 类型需要使用%Lf

具体标准(C99)如下:

image-20210409173302756

image-20210409173314667

image-20210409173324188

多行注释的问题

注意 C 语言的多行注释是不会嵌套的。看下面的例子:

1
2
3
4
/*
Change "username" and "password" to /* your account's identity. */
Enjoy!
*/

多行注释自 第一个 /* 起 ,至 第一个 */ 止 ,中间的一切 /* 均做注释内字符串而不是多行注释起始符进行处理。如上面例子,多行注释在第二行截止,第三行的Enjoy! 和第四行的 */ 均不在多行注释内。

作者

Zhou Weitong

发布于

2021-08-12

更新于

2021-08-15

许可协议

评论

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×