1、结构体
自定义的一种数据类型,将一类事物的数据集合在一起显示。
例如描述人的属性集合
typedef struct peeople
{
char name[20];
int age;
}peo;加上typedef给数据类型struct people起一个别名。
结构体变量通过.访问,例如:peo.age;结构体指针变量通过->访问,例如:peo->age。
2、字节对齐
以32位 OS为例:
char: 1 short:2 int:4 long :4 float:4 duoble :4,但是写两次。
对齐方式像最大字节对齐。例如上面结构体类型大小为:24,有一种很特殊的情况:
struct kpl
{
char a;
short b;
char c;
int d;
};
该数据类型大小类型是多少呢?是8?并不是,是12!
存取过程如上图所示 。short取的字节是2,留下的是偶数个。
看到char字节申请的空间有所浪费,大字节类型放在最前可以减少一些浪费。另一种方位是位域或位段,例如int a=8,8占用了4个比特,并没有用到4个字节,可以写成int a:4;但是标准输入不能输出位域或位段的结果。
3、内存分区
了解内存的分布情况,利于对指针的更深刻了解。
对于堆区,最常用的是malloc和free,两个函数是一起使用,malloc负责向堆区开辟空间,free负责将申请的空间释放。 还有一个函数是memset,对申请的空间进行一个填充,也就是赋初值。4、makefile工程管理
在写函数中,有许许多多的.c文件,一个一个编译好像太慢了,makefile正好解决这个问题。
了解makefile的工作方式,先了解一下linux中gcc的编译流程。
预处理(处理以#开头的文件):gcc -E stu.c -o stu.i
编译(生成汇编语言):gcc -S stu.i -o stu.s
汇编(将汇编语言转成及其代码):gcc -c stu.s -o stu.o
链接(将所有的机器代码汇集生成一个可执行文件):gcc stu.o -o stu
makefile负责将前三个步骤合在一起,四步变两步。同时建立四个文件夹include,src.obj,bin。
include里面放着头文件,src放着.c文件,obj里面放着可执行文件,bin里面放着可执行文件。
在四个文件夹的同一层目录建立一个主makefile,在src,obj目录下创建一个副makefile,主makefile负责调用副makefile和清除src和obj生成的可执行文件和目标文件。
其中一些变量意义如下:
CC :编译器选项的名称,默认为cc
CFLAGS:编译器的选项,无默认值
RM:程序删除的名称,默认为rm -f
OBJ和OBJS,一个用于存放可执行文件,一个用于存放所有的依赖文件
$@:目标文件
$^:所有的依赖文件
$<:第一个依赖文件
其中还涉及到头文件:两者区别如下
“”:编译器从用户的工作路径开始搜索头文件
<>:编译器从系统库路径(/usr/include)下开始搜索头文件
还有一个避免头文件的应用,#include<stdio.h>引用多次不会报错,而#include "a.h"多次引用则会报错,
#ifndef 标号(一般用大写表示,把.变成_)
#define 标号
- 头文件
- 宏定义
- 结构体类型的定义
- 枚举类型的定义
- 函数声明
#endif
则能避免头文件的重复引用带来的错误。
5、枚举和共用体
枚举的作用是代码能变得更语义化。共用体union的作用主要是判断大小端的存储模式。