C语言必备知识1(预处理,宏定义,内存分配)

C语言预处理

C 预处理器是一个文本替换工具

所有的预处理器命令都是以井号(#)开头。下面列出了所有重要的预处理器指令:
指令    描述
#define    定义宏
#include包含一个源代码文件
#undef    取消已定义的宏
#ifdef    如果宏已经定义,则返回真
#ifndef    如果宏没有定义,则返回真
#if    如果给定条件为真,则编译下面代码
#else    #if 的替代方案
#elif    如果前面的 #if 给定条件不为真,当前条件为真,则编译下面代码
#endif    结束一个 #if……#else 条件编译块
#error    当遇到标准错误时,输出错误消息
#pragma    使用标准化方法,向编译器发布特殊的命令到编译器中
================================================================

分块记忆为

define undef
if elif else endif
ifdef endif
ifndef endif
error
pragma

================================================================




C提供的三种预处理(gcc -E)功能:
文件包含
条件编译
宏定义


-------------------------------------------------------------

什么是宏?
宏就是替换
宏定义末尾不加分号

-------------------------------------------------------------
宏定义是C提供的三种预处理功能的其中一种,这三种预处理包括:宏定义、文件包含、条件编译

宏定义又称为宏代换、宏替换,简称“宏”。
格式:
#define 标识符 字符串
其中的标识符就是所谓的符号常量,也称为“宏名”。
预处理(预编译)工作也叫做宏展开:将宏名替换为字符串。
掌握"宏"概念的关键是“换”。一切以换为前提、做任何事情之前先要换,准确理解之前就要“换”。
即在对相关命令或语句的含义和功能作具体分析之前就要换:
例:
#define PI 3.1415926
把程序中出现的PI全部换成3.1415926
说明:
(1)宏名一般用大写
(2)使用宏可提高程序的通用性和易读性,减少不一致性,减少输入错误和便于修改。例如:数组大小常用宏定义
(3)预处理是在编译之前的处理,而编译工作的任务之一就是语法检查,预处理不做语法检查。
(4)宏定义末尾不加分号;
(5)宏定义写在函数的花括号外边,作用域为其后的程序,通常在文件的最开头。
(6)可以用#undef命令终止宏定义的作用域
(7)宏定义不可以嵌套
(8)字符串" "中永远不包含宏
(9)宏定义不分配内存,变量定义分配内存。
(10)宏定义不存在类型问题,它的参数也是无类型的。


---------------------------------------------------------------------------------------------------------------------------------------------------------------------

C 内存管理
C 语言为内存的分配和管理提供了几个函数。这些函数可以在 <stdlib.h> 头文件中找到。

1    void *calloc(int num, int size);该函数分配一个带有 num 个元素的数组,每个元素的大小为 size 字节。
2    void free(void *address);该函数释放 address 所指向的h内存块。
3    void *malloc(int num);该函数分配一个 num 字节的数组,并把它们进行初始化。
4    void *realloc(void *address, int newsize);该函数重新分配内存,把内存扩展到 newsize。


=================================================================

简记:

alloc(allocate)分配

* mallac()
* calloc(num,size);
* realloc(*address,int newsize);

void free(*address);

=================================================================

Linux下对编译后的可执行文件Test使用size命令,结果如下:

size Test
   text       data        bss        dec        hex    filename
   1197        504         16       1717        6b5    Test

可以看出,此可执行程序在存储时(没有调入到内存)分为代码区(text)、数据区(data)和未初始化数据区(bss)3个部分。


栈和堆的区别

栈是由编译器在需要时分配的,不需要时自动清除的变量存储区。里面的变量通常是局部变量、函数参数等。堆是由malloc()函数(C++语言为new运算符)分配的内存块,内存释放由程序员手动控制,在C语言为free函数完成(C++中为delete)


C程序执行时的内存分配情况如注释所述:

//main.cpp 
int a = 0;    //a在全局已初始化数据区
char *p1;    //p1在BSS区(未初始化全局变量)
main()
{
int b;    //b在栈区
char s[] = "abc"; //s为数组变量,存储在栈区,
//"abc"为字符串常量,存储在已初始化数据区
char *p1,p2;  //p1、p2在栈区
char *p3 = "123456"; //123456\0在已初始化数据区,p3在栈区
static int c =0;  //C为全局(静态)数据,存在于已初始化数据区
//另外,静态数据会自动初始化
p1 = (char *)malloc(10);//分配得来的10个字节的区域在堆区
p2 = (char *)malloc(20);//分配得来的20个字节的区域在堆区
free(p1);
free(p2);
}
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值