1.在windows中,双击的本质是运行该程序,就是将程序(.exe)加载到内存当中去。任何程序在被运行之前都必须加载到内存当中去。
2.所有的变量本质都是在内存的某个位置开辟的。变量不能定义在硬盘上,因为变量必须在程序运行的时候才能被开辟,程序要运行,就必须在内存中。
3.定义的本质就是开辟一段空间,只能有一次,声明的本质是告知,可以进行多次。
4.register修饰的变量,不能取地址(&)。
5.所有的变量声明的时候不能设置初始值,因为没有开辟空间。
6.跨文件使用,变量必须要声明,函数可以不声明,但是会有一个警告。实际上警告就是编译的时候没有找到,但是链接的时候又找到了。
7.变量和函数在.h文件中声明的时候,尽量写上extern。变量必须带上extern,虽然不写不会报错,但是,不写的话编译器可能会认为是定义,而不是声明。
8.static修饰的全局变量,该变量只能在文件内被访问,不能被外部其他文件直接访问,但是可以间接访问,通过函数。
也就是假设A文件中的一个全局变量被static修饰, B文件是无法访问该变量的,但是如果A文件中包括一个函数,该函数内部包括了该全局变量, B文件通过访问这个函数,间接访问到了这个变量。
9.static修饰函数,用法同上,利用另一个函数进行间接访问。
10.(重点)被static修饰的局部变量,生命周期延长了,但是它的使用范围并没有变。出了大括号,就不能使用。
9.栈区先使用高地值,再使用低地址。堆区相反。
10.命名:见名知意,大小驼峰。数字,字母,下划线。
11.数据存进变量的时候已经转化成补码了,和数据本身的正负号没有关系。变量只是一块空间存取数据而已。具体输出出来是什么数,要看%后面。
12.大端存储:按照字节为单位,低权值位数据存在高地之处。
13.小端存储:按照字节为单位,低权值位数据存在低地址处。
14.cpu计算最先单位为int,注意整型提升和截断。
15.规定1000 0000为-128。
16.计算机中所有计算都转换为加法,用补码计算。
17.注意'\0','0',0的区别。第一个和第三个是一个意思。
18.所有的无符号类型建议在后面加一个u。
19.if (0){;}这样写也可以注释代码,但是不推荐。
20.c99中有_Bool类型,#define为bool类型。
现在用的c语言标准是c89或c90,没有true和false,但是c99中有。占用一个字节。
21.微软提供了一个,BOOL x = TRUE
全大写的,大小为4个字节。但是只有微软的编译器才能使用。
22. C90使用int代替bool,0为假,其它都为真(负数)。
23.浮点数存储会有精度损失。
24.浮点数在进行比较的时候,绝对不能使用==。
25.浮点数比较要精度。fabs(x - y) < EPS。
26.fabs的参数为double型,返回值也是double型abs的参数为int型,返回值也是int型。abs是求一个整数的绝对值,而fabs是求一个实数的绝对值。
27.系统默认精度。
DBL_EPSILON double
FLT_EPSILON float
要使用头文件<float.h>
28.浮点数精度比较不能加=。
29.'\0'和0和NULL意思是一样的。
30.#define NULL ((void *)0)
31.强制类型转换,该数的本质并没有发生变化。
32.else就近匹配,建议使用大括号。
33.#pragma warning(disable:4996)屏蔽报错
#define _CRT_SECURE_NO_WARNINGS 1
以上两种写法作用相同。
34. case和break之间不能定义变量。如果非要这么做的话,加一个大括号,把它变成一个完整的代码块。一般不推荐这样使用。如果非要这样做,将它分装成一个函数,调用函数使用。
35.case 后面可以使用return,但是不建议这样使用。
36.switch(),括号用户推荐使用布尔值。
37.case后不能使用const修饰的常变量。
38.switch语法结构中,case完成的是判定功能,break完成的是分支功能,default处理异常情况。
39.default推荐放在结尾。
40.任何C语言程序,在默认编译好之后,运行时都会打开三个输入输出流。
stdin:标准输入,FILE* stdin,键盘。
stdout:标准输出,FILE* stdout,显示器。
stderr:标准错误,FILE* stderr,显示器。
41.显示器打印出来的都是字符。printf()返回指示字符的个数。
42.键盘和显示器称为字符设备。
43.嵌套循环的时候,尽量把循环次数多的放在内侧,循环次数少的放在外侧。
44.循环尽量写半闭半开区间。好处是右边就是循环次数(左边从0开始)。如果左边不是从0开始的,循环指数就是右边减左边。
45.for循环,()中尽量不要使用浮点型。
45.goto不能跨越代码块,即{}。建议不要使用。
46.void 不能定义变量,vs中sizeof(void) == 0
gcc中为1。
47.int test(),虽然没有定义参数,但是可以传参(不被使用),编译器不会报错。
int test(void),如果传参,vs有警告,gcc会报错。
48.void*指针可以被任意类型指针接收,也可以接收任意指针类型接收。
49.vs中void*指针不能加减,因为大小不明确。gcc可以。
因为栈帧结构在函数调用完毕会被释放,所以定义的临时定量也会被释放。
50.return语句不可返回指向栈内存和指针,因为该内存在函数体结束时被自动销毁。
51.函数的返回值具有常量属性。
52.char* p = "hello"
后面的内容被放到了内存中的常量区。所以内容不能被修改。
53.取地址(&),取的是地址最低的那个(一个int 型变量有4个地址)。在C语言中,不管什么类型变量,取它的地址永远取的是最低位的地址。(和大小端没有任何关系)
54.const int* p = &a;
int* q = (int*)p;
如果不加括号里的东西,编译器会警告。
int* p = &a;
const int* q = p;
编译器不警告。
55. C语言函数传参一定会产生临时变量,包括指针。
56.volatile作用是不要cpu优化,这个关键字一般不使用,除了多线程等情况下。
57.const volatile int a;这两个关键字不冲突,const 要求你不进行写入,volatile 意思是读取时,每次从内存中读,两者不冲突。
虽然volatile叫做易变关键字,但是仅仅描述它修饰的变量可能会变化,要编译器注意,并不是它要求对应变量必须变化。
58.在gcc中,空结构体大小为0。
59.联合体(union)中,所有成员以及自身的起始地址都是一样的,为最低地址,呈放射状。
60.如何判断大小端?第一是使用联合体,第二是使用指针。
61.联合体要求内存对齐(其大小能整除任何一个成员)。
62.int* a,b;
a和b的类型不一样, a是指针,b是整型。
typedef int* int_p;
int_p a,b;
或者int* a,*b;
这样写的话,a和b都是指针类型。
#define int_p int*;这是纯粹的文本替换。
typedef定义之后是一种独立类型。