目录
  • 1. C/C++中内存大致分的三个区域
  • 2. 关键字static
    • 静态局部变量
    • 静态全局变量
    • 静态函数
  • 3.#define 定义常量和宏
    • #define 定义常量
    • #define 定义宏
  • 4.关键字 typedef

    1. C/C++中内存大致分的三个区域

    栈区(stack):由编译器自动分配释放。

    存放 :局部变量、形参、返回值。

    堆区 (heap): 由程序员分配内存和释放。

    调用函数 :malloc() free()等。

    静态区 :通常是用于那些在编译期间就能确定存储大小的变量的存储区,全局变量和 静态变量。

    C语言中那些你必须知道的常用关键字

    2. 关键字static

    在C语言中:

    static是用来修饰变量和函数的

    1. 修饰局部变量-称为静态局部变量

    2. 修饰全局变量-称为静态全局变量

    3. 修饰函数-称为静态函数

    静态局部变量

    示例:

    大家来来看这段代码

    C语言中那些你必须知道的常用关键字

    局部变量a,在没有static修饰之前局部变量a是存放在栈区的。所以每次出局部范围就销毁(把空间还给操作系统)。然后,调用时重新创建初始化。

    那我们把局部变量a加上static关键字修饰成静态局部变量,会怎么样呢?

    //static 修饰局部变量的时候
    //本来一个局部变量是存放在栈区的,如果被static修饰就存储到静态区了
    //static 修饰局部变量改变了变量的存储类型(位置),使得这个静态变量的生命周期变长了,直到程序结束才结束
    //但是作用域不变
    void test()
    {
    	static int a = 5;//静态变量的
    	a++;
    	printf("%d ", a);
    }
    int main()
    {
    	int i = 0;
    	while (i < 10)
    	{
    		test();
    		i++;
    	}
    	return 0;
    }

    C语言中那些你必须知道的常用关键字

    这里static关键字把变量a修饰成了静态变量,所以变量 a a a 本来是存放在栈区的,但是由于被修饰成静态变量所以被存放在静态区了。

    静态区变量的特点:

    创建好后,直到程序结束才销毁

    C语言中那些你必须知道的常用关键字

    这里说明了:静态变量a在程序编译的时候就自动创建好了,并且已经完成初始化了

    而没有修饰呢:

    C语言中那些你必须知道的常用关键字

    没有修饰之前必须进入函数体中初始化语句才会完成初始化。

    静态局部变量的作用域和生命周期

    前面我们说了静态变量是创建完成后,直到程序结束才销毁。

    所以,静态变量的生命周期是整个工程。

    而静态局部变量的作用域呢?

    虽然我们把变量a修饰成了静态局部变量但是他本质上还是个局部变量

    所以他的作用域不变还是它所在的局部范围

    静态全局变量

    我们都这样全局变量的作用域是

    整个工程

    C语言中那些你必须知道的常用关键字

    可以看到只要在一个工程内,不同.c文件之间只要(声明)也可以调用。

    说明:全局变量具有外链接属性。

    但是我们用static关键字修饰成静态全局变量看看

    C语言中那些你必须知道的常用关键字

    说明:static 修饰全局变量

    • 改变了这个全局变量的链接属性,由外边链接属性变成了内部链接属性
    • 就是这个静态变量只能在自己所在的源文件内部使用,不能在其他源文件内部使用了
    • 感觉像是作用域变小了

    静态函数

    static修饰函数和修饰全局变量是一样

    C语言中那些你必须知道的常用关键字

    用static修饰函数了之后

    C语言中那些你必须知道的常用关键字

    说明:用static修饰函数

    • static 修饰函数和static修饰全局变量是一样的
    • 函数是具有外部链接属性的,但是被static修饰,就变成了内部链接属性
    • 使得这个函数只能在自己所在的源文件内部使用,不能在其他文件内部使用的

    3.#define 定义常量和宏

    #define 定义常量

    #define M 100
    int main()
    {
    	int arr[M] = {0};//100*4 = 400
    	int m = M;
    	printf("%d\n", sizeof(arr));//400
    	printf("%d\n", M);
    	printf("%d\n", m);
    	return 0;
    }

    这里#define 定义的是M这个标识符常量

    • 以后我们在碰到M的时候编译器在编译期间,就会自动替换为常量100
    • 通常在定义数组时使用或者重复值时。

    #define 定义宏

    我们来看一下宏是怎么定义的:

    C语言中那些你必须知道的常用关键字

    和定义函数非常相识

    C语言中那些你必须知道的常用关键字

    但是宏没有函数的返回类型和参数类型

    还是很不一样的,宏的实现体一般都是表达式

    那么宏是怎么调用的呢?和函数有什么区别嘞?

    //宏
    #define ADD(x, y) ((x)+(y))
    //函数
    int Add(int x, int y)
    {
    	return x + y;
    }
    int main()
    {
    	int a = 10;
    	int b = 20;
    	int c = ADD(a, b);
    	//int c = (a)+(b);
    	printf("%d\n", c);
    	int d = Add(a, b);
    	printf("%d\n", d);
    	return 0;
    }

    我们可以看到宏的调用也和函数产不多,但是

    int c = ADD(a, b);这段代码调用宏的本质是替换

    int c = (a)+(b);在编译的时候就把ADD这个宏替换成这样

    而函数调用是

    把实参传到函数形参里面进行计算,然后在返回值

    4.关键字 typedef

    typedef 顾名思义是类型定义,这里应该理解为类型重命名。

    示例:

    //将unsigned int 重命名为uint_32, 所以uint_32也是一个类型名
    typedef unsigned int uint_32;
    int main()
    {
        //观察num1和num2,这两个变量的类型是一样的
        unsigned int num1 = 0;
        uint_32 num2 = 0;
        return 0;
    }
    声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。