第21节 CC语言之预处理和内存管理


预处理

      所谓预处理指的是预处理指令,它是由编译器的一个组件,预处理器来负责处理的指令。


预处理指令一共分为三类。


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。双向链表就是指有连个指针域,一个指向下一个节点,一个可以指向上一个节点。循环链表就是指尾节点指向头节点的链表。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值