预处理
所谓预处理指的是预处理指令,它是由编译器的一个组件,预处理器来负责处理的指令。
预处理指令一共分为三类。
1、文件包含
#include <stdio.h>,#include "stu.h ",#import <>,"",他们都表示是文件包含的意思,就是把<>,""中的内容复制到当前文件中去,<>作用就是在使用系统函数(库函数)的时候用的,优先在系统目录下查找,“”一般是引用咱们自己定义头文件用的,优先在当前目录下查找。工程中查找。
实现防止头文件被循环引用。
2、宏替换 宏定义
就是用一个大写字母或大写的字符串,来表示它后面的文本信息。
2.1、宏常量
# 是预处理指令的标志,# 预处理指令是一条空指令
#define 作用定义宏
#define N 10
就是用数字10 替换 N
#define PI 3.14
#define MAX_NUM 100
#define MIN_NUM 0
#define PORT 8080
#define SERVER 218.213.142.206
#define PATH "/Users/tarena/Desktop/a.txt"
#define HOME "/Users/tarena"
#define COMMAND "ping 127.0.0.1"
int a[MAX_NUM];
2.2、宏和表达式
#define SUM a*a
2.3、宏和函数(带参的宏 宏函数)
#define MAX(a,b) (a)>(b)?(a):(b)
2.4、多行的宏(例子单例宏)
#define FUN (a,b) (a)>(b) \
ajflksjflksjdlkfjslkdjfkls\
dajfslkdjfalsdfjlsjdfkls\
lkajsdlkjflkaskldfkla\
sjalfjalskfjkldjslkjfdslfjsk\
dsafsljfdklsd
3、条件编译
#ifndef MY_H
#define MY_H
….
#endif
4、内存管理
1.系统级的内存管理 用户级的内存管理
操作系统层面
void *calloc(size_tcount,size_t size);
void free(void *ptr);
void *malloc(size_t size);
void *realloc(void *ptr, size_t size);
物理内存
256M ~ 16GB 32GB
64GB 128GB
虚拟内存
页面文件
内存映射--->页面文件
mmap
brk,sbrk
2.用户级的内存管理
2.1 静态内存分配 编译器做的
自动分配内存空间,自动回收内存空间。不用程序员手动的去干预,那么这些个变量都被放在栈内存空间中,栈内存比较小,一般为10M~30M左右。栈是一种数据结构,后进先出型的数据结构。
例子:弹夹 浏览器(前进 后退)Word文本编辑软件,PS软件。
2.2 动态内存分配 程序员做的
手动内存管理,需要使用malloc函数动态的向堆内存空间取手动申请内存空间,堆内存中所有的变量(对象)都是匿名的变量或对象,没有变量名称。所以只能通过指针这种快捷方式,找到堆内存中空间中得地址,通过地址找到它存储的数据,堆内存一般比栈内存要大的多。需要程序员手动申请,并且在使用完毕时手动释放堆内存,如果是在安装有操作系统的前提下,当程序运行结束后,如程序员忘记了回收内存,(内存泄露了)操作系统会主动的回收该内存空间。所以在我们手动内存管理的时候要遵循着 谁创建,谁释放的原则,创建和释放是成对出现的。
要么就是该释放时,没有释放。
要么就是不改释放时,你释放了。
3.借助 malloc()函数分配内存
<stdlib.h>头文件中 在使用时要先引入头文件
void *malloc(size_t size);
1.函数原型
void *malloc(size_t size);
函数的返回值
void * 通用指针(void *)泛型 万能指针,但是void* 不能做取值运算,强制类型转(int*) 再做取值运算。
只要是64位系统中,不管什么类型的指针都占 64/8 = 8字节。32位系统中4个字节。
参数:标识符 传要分配的内存的大小
free(void *p);
5.C语言程序在执行过程中所占内存的情况
1.栈 stack
它是在程序运行时才出现的,由编译器自动分配内存和回收(释放),函数的返回值,函数的参数,函数中得局部变量等都是存放在栈中得。int *p 变量p就是在栈中。一般比较小
10~30M,是后进先出型的数据结构。
栈又 堆栈,是用户存放程序临时创建的局部变量用的,fun
{
}(特殊不包括使用static修饰的函数或变量),static在数据段。函数调用 ,递归调用时就会频繁的出栈和入栈。
2.堆 heap
堆也是在程序运行时才出现的概念,一般由程序员动态申请内存空间和释放内存空间,如果有操作系统下,由操作系统进行回收。堆是用于存放在程序运行中被动态分配的内存空间,是匿名的空间,使用时需要用一个指针来指向堆内存空间才能够访问。
3.数据段 data
主要存放全局变量、以及静态变量(static)、常量。根据我们存储的数据的类型 只读数据段roData 可读可写数据段,rwData 上边这个数据段,声明并初始化了的, 还包括了BSS段,声明了没有进行初始化的变量都被存放到BSS段。
4.文字常量区
字符串常量就是存储在这个区域的"Hello World",程序运行结束后于系统自动释放。
5.代码段
就是编译器把C语言的程序 编译生成可执行的代码都按照顺序存储在该段数据中,计算机的CPU会从第一条代码开始依次向下逐条的去执行。
链表:
1.链表和数组都统称为线性表,数组是线性表的顺序存储,只的时内存地址是连续的,线性的关系。内存分配在栈中,而链表是线性表的链式存储,内存可能是连续的可可能是不连续的,内存地址被分配在堆空间中,由指针相互连接。
2.链表的分类
2.1 单链表
2.2 双链表
2.3 循环链表
3.构成链表的最小单位 节点
3.1 节点的构成 由 指针域 和 数据域两部分组成。
struct Node
{
int data;//数据域
struct Node * next;//用于指向下一个节点
};
一般我们在学习过程中学习都是单链表,单链表的特点就是尾节点指向NULL。双向链表就是指有连个指针域,一个指向下一个节点,一个可以指向上一个节点。循环链表就是指尾节点指向头节点的链表。