C语言重要知识点总结(一)

最近重新看了下C语言,发现先前学习的时候很多的重点都被忽略了,现在回头看发现了很多以前没有注意的东西,所以写博客记录下,方便以后可以参考查询。

  1. 变量的存储类别

    C语言中变量的存储类别有auto,register,extern和static。下面将对以下四个存储类别进行详细的介绍:
    auto:自动变量,默认的存储类型,根据变量定义的位置决定变量的生命周期和作用域。如果定义在任何一个函数的外面则编译器将改变量定为全局变量。如果定义在函数里面,则编译器则会将改变量识别为局部变量。
    register:寄存器变量,这个类别的变量会被优先分配到寄存器。通常作为循环因子的变量会被分配到寄存器。
    extern:外部变量(全局变量),该关键字用来扩展全局变量的作用域。扩展的范围是从使用extern变量开始到改文件结尾。extern关键字所做的工作只是让其他文件中的程序可以引用该变量,并不会改变这个变量的生命周期。extern修饰的一定是全局变量,修饰局部变量没有意义。
    static静态变量,以前以为用static修饰的变量是存放在堆中的,现在觉得不是。static是用于限制作用域的,被static修饰的变量存储在数据段中,无论static修饰的是全局变量还是局部变量都是被存放在数据段中的。被static修饰的变量可以细分为static全局变量和static局部变量。下面对分别对static全局变量和static局部变量从作用域和生命周期进行总结:

    staitc变量作用域生命周期
    staitc全局变量只作用于本文件,也就是说只有本文件的函数可以引用改全局变量。在整个程序执行过程中该变量一直存在。
    staitc局部变量作用域和普通的局部变量一样,只能作用在其所定义的复合语句中,也就是其他函数不可访问。在整个程序执行过程中该变量一直存在,因为不是存放在栈中而是存放在数据段内。

    正是被static修饰的变量有如上的特性,所以static变量在C语言中有一个很显著的作用就是可以实现一个模块的封装。在C语言中一个源程序文件就是一个模块,由于被static声明的全局变量只能被本文件的函数访问,所以当用户在一个文件中定义一个static全局变量后,其他文件(模块)只能通过该模块提供的接口函数来访问这个static变量,而不能直接对其进行操作。

    2. 数组指针和指针数组
    这两个概念是我自己总结,其实自己也有点迷糊。数组指针是指数组的指针,而指针数组是指指针的数组。
    指针数组:指针的数组好理解,就是存放指针的数组,在C语言中定义如下:

        int *p[10];

该定义指定了一个存放10个指向int的指针的数组。
数组指针:数组的指针,顾名思义,就是指指向一个数组的指针。在C语言中的定义如

        int (*p)[10];

一个指针,指向一个数组对象,该数组是一个拥有10个整型元素的数组。
注意:当执行P+1是,p移动的字节数不是int的字节数,而是整个数组的字节数。如上面的定义,当执行p+1时,移动的是sizeof(int)*10=40个字节。
3. 内存对齐
为了高速的处理数据,现代处理器的设计引入了对齐的概念。所谓对齐就是保证数据在内存中的存储时地址变化按照一定的规律,主要目的是保证CPU每次都可以取同样长度的数据进行运算,因此可以提高计算机运行的速度。是一种用空间换时间的策略。

struct test1{
    char ch;
    short s;
    int i;
}

在32位体系结构中定义如上的结构体。用sizeof()测试上面结构体的大小的结果是8字节

struct test2{
    char ch;
    int i;
    short s;
}

在32位体系结构中定义如上的结构体。用sizeof()测试上面结构体的大小的结果是12字节
出现上面的现象就是由于内存对齐。在32位体系结构中默认采用4字节的对齐方式。也就是说CPU一次读取字节的大小为4个字节。当只有一个字符变量的时候,第一个字节存储字符变量的值,剩下的3个用空白值填充。当对于结构体test1中的情况是将字符型变量ch和短整型变量存储在一个4字节的内存区域,多出的一个字节用无用值填充。所以测试的结果是8字节。用图形表示如下:

更多推荐

C语言重要知识点总结(一)