1:结构体定义
不同数据类型的集合。当用不同数据类型的数据去描述一个对象(事物)时,常常用到结构体。
结构体是用户自定义的新数据类型,在结构体中可以包含若干个不同数据类型和不同意义的数据项(当然也可以相同),从而使这些数据项组合起来反映某一个信息。
2:结构体语法
1: 如何创造一个结构体数据类型。
三种方式创建结构体:
1-a: 先创建结构体数据类型,再定义变量
定义一个结构体类型的一般形式为:
struct 结构体名
{
数据类型 成员名1;
数据类型 成员名2;
:
数据类型 成员名n;
};
例如:
struct work
{
char name[32];
short int age;
char sex;
float salary;
};
struct work: 结构体数据类型名(相当于int),注意: 此时不开辟内存空间。
{}:在大括号中的内容也称为“成员列表”或“域表”,成员列表中的数据类型可以是基本变量类型和数组类型,或者是一个结构体类型;
1-b:再创建结构体类型的同时,定义变量,
1-c:再创建结构体类型的同时,定义变量,但是没有结构体数据类型名。变量只能在创建结构体类型的同时定义。
2: 如何定义相对应的结构体数据类型变量
struct work w1; 定义一个结构体数据类型的变量w1, 此时w1会开辟内存空间,
内存空间大小: 用sizeof(w1) 或者sizeof(struct work)。
3: 如何访问数据元素
3-1: 第一种访问方式".": 结构体成员选择运算符。
变量名.数据成员变量名。
例如:w1.age = 30;
printf("name: %s\n", w1.name)
4: 如何对结构体变量初始化。
5: 什么是结构体数组
数组的元素为同一种结构体类型的变量。
6: 什么是结构体指针
结构体数据类型名 *结构体数据类型指针变量。
struct work *wp; wp就是一个结构体指针变量,用来存放结构体变量的地址。
7: 结构体在函数传参中的使用。
补充: 在底行模式下。
: n,m co x:将第n~m行的内容复制到第x行,
: n,m co .:将第n~m行的内容复制到第光标所在的行,
:n,ms/oldstring/newstring/g : 将第n~m行的oldstring替换为newstring。
3:结构体字节对齐
硬件为了访问方便快速,
struct work
{
int a;
char b;
};
sizeof(struct work) = 8;
规则:
4:共用体
构造数据类型,1:数据成员的各个元素的首地址相同,2:共用体的大小=成员中长度最大那个值。
union 共用体名
{
成员表列;
};
5:存储类型
auto: 默认用来修饰局部变量(函数或代码块中的变量)。它不能修饰全局变量,
auto类型的变量:
生命周期: 从函数执行开始分配空间,函数执行结束空间释放掉。
作用域(这个变量可以被谁调用): 只能在函数内部使用。
存放位置: 存放在内存的栈空间。
register:寄存器类型,用来修饰局部变量,试图将此变量存放在寄存器中,我们无法获取此变量的地址。
register类型的变量:
生命周期:从程序开始执行,直到程序执行完毕
作用域(这个变量可以被谁调用): 只能在函数内部使用
存放位置: 存放在cpu的寄存器中。
static: 静态存储
static类型的局部变量: 被static修饰的变量生命周期延长到和全局变量相同。
生命周期: 从函数开始执行到程序(.c文件)执行结束。
作用域(这个变量可以被谁调用): 只能在函数内部使用
存放位置:存放在内存的静态空间,
static修饰的全局变量:
只要在多文件编程中,static修饰的全局变量和函数才有意义。
static修饰的全局变量,
生命周期: 从函数开始执行到程序(.c文件)执行结束。
作用域(这个变量可以被谁调用): 只能在本文件中使用。
存放位置:存放在内存的静态区。
staic修饰的函数:
只能在本文件中被调用,
extern: 外部链接
多文件编程中,对于全局变量
默认的存储类型是extern,对于多个文件中都定义了同一个变量,那么只能有一个文件中初始化这个变量表示开辟
空间存储这个值,其他文件存储类型为extern,表示在本文件中不开辟空间只是调用其他文件中的变量。
多文件编程中,局部变量的默认值不是extern。
6:动态内存分配
变量存放在内存的位置: 1:栈区(局部变量), 2:常量区(static修饰的变量,全局变量) 3:堆区(动态申请的内存)
malloc/free
void * malloc(size_t num)
功能:动态分配存储空间。
参数: num:要申请的空间大小。
返回值: 成功申请到空间,返回申请到的内存首地址, 失败,返回NULL.
void free(void *p)
功能:手动释放malloc申请的空间
参数:p: malloc申请的空间的首地址。
返回值: 无返回值。
7:条件编译
有两种方法:
方法一:根据宏是否被定义
#ifdef D_E
{
code 1
}
#else
{
code2
}
#endif
说明: 如果宏D_E已经定义过条件为真,那么就编译code1的内容,注释掉code2的内容。
如果宏D_E没有定义过,那么就编译code2的内容,注释掉code1的内容。
#ifndef D_E
{
code 1
}
#else
{
code2
}
#endif
说明: 如果宏D_E已经定义过条件为假,那么就编译code2的内容,注释掉code1的内容。
如果宏D_E没有定义过,那么就编译code1的内容,注释掉code2的内容。
方法二:根据宏的值
#if <macro>
code 1
#else
code 2
#endif
说明:如果宏macro的值为0条件为假,那么就编译code2的内容,注释掉code1的内容。
否则条件为真,那么就编译code1的内容,注释掉code2的内容。
8:make工具
make是一个自动编译工具:
1: 根据文件的时间戳来判断此文件是否要编译。
时间戳:(文件的修改时间)。
2: 通过读取Makefile的内容来执行编译命令。
Makefile格式
target : dependency_files
<TAB> command
当在命令行输入make时,
将Makefile中的第一个目标文件做为make的最终目标。
变量定义的四种方式
(常用方式) 递归展开方式VAR=var
简单方式 VAR:=var
VAR ?= var: 当VAR的值为空时,将VAR赋为var, 如果不为空则保持原来的值。
VAR += var:在VAR原来内容后面追加var。
自动变量
$* 不包含扩展名的目标文件名称
$+ 所有的依赖文件,以空格分开,并以出现的先后为序,可能包含重复的依赖文件
(常用)$< 第一个依赖文件的名称
$? 所有时间戳比目标文件晚的的依赖文件,并以空格分开
(常用)$@ 目标文件的完整名称
(常用)$^ 所有不重复的目标依赖文件,以空格分开
$% 如果目标是归档成员,则该变量表示目标的归档成员名称
选项
-C dir读入指定目录下的Makefile
-f file读入当前目录下的file文件作为Makefile
-i忽略所有的命令执行错误
-I dir指定被包含的Makefile所在目录
-n只打印要执行的命令,但不执行这些命令
-p显示make变量数据库和隐含规则
-s在执行命令时不显示命令
-w如果make在执行过程中改变目录,打印当前目录名
掌握:
-C:指明make要读取的Makefile的路径。
-f: 指定文件作为make的读入文件。