点击我的视频网校,学习编程课程,或者关注我的微信公众号“编程之路从0到1”,了解课程更新

1.8语法补充

本教程视频已同步到B站: 程序员的C——实用编程,不玩虚的!

语法补充

共用体

结构体的各个成员会占用不同的内存,互相之间没有影响;而共用体的所有成员占用同一段内存,修改一个成员会影响其余所有成员。结构体占用的内存大于等于所有成员占用的内存的总和(内存对齐),共用体占用的内存等于最长的成员占用的内存。共用体使用内存覆盖技术,同一时刻只能保存一个成员的值,如果对其他成员赋值,就会覆盖掉原来成员的值。

union data{
    int n;
    char c;
    short s;
};

// 在结构体中声明
struct person{
    char name[20];
    char sex;
    short age;
    union{
        float score;
        char course[20];
    } sc;
};

变长数组和柔性数组

在C99之前,数组的长度必须是整数或者常量表达式, 而C99则做了改进,允许数组长度是变量。这种数组称为变长数组(variable-length array)。

int len = 10;
char str[len];

变长数组需要注意一点,不能在声明的同时初始化。譬如:char str[len] = {0};编译报错。可以使用memset(str, '\0', len);来做零值初始化。

柔性数组(Flexible Array)也是C99引入的一个新特性。它允许你在定义结构体的最后一个元素时,声明一个长度为0的数组,而这个数组的大小可以在程序运行的过程中动态设定。

typedef struct {
    int len;
    int array[0];  //可省略0,写作:int array[]
} MyArray;

柔性数组小结:

  1. 结构体中的最后一个元素允许是未知大小的数组,称为柔性数组成员
  2. 结构体中的柔性数组成员前面必须至少包含一个其他成员
  3. sizeof返回的此结构体大小时不包括柔性数组内存(即柔性数组不占用结构体内存)

思考:结构体中的柔性数组和指针有什么区别?为什么使用柔性数组?

//  定长缓冲区
struct Buffer {
    int   len;
    char  data[MAX_LEN];
};

由于缓冲区的大小是在编译时无法确定的,为了能适应各种场景,只能把缓冲区大小定得尽可能大,但也不能太大,这种情形下,往往存在浪费内存的问题。

有一种解决办法,就是把结构体中数组字段换成指针:

struct Buffer {
    int   len;
    char  *data;
};

但是这样一来,就需要对结构体进行两次动态内存分配:

buf = (struct Buffer *)malloc(sizeof(struct Buffer));
if(buf != NULL){
    buf->data = (char *)malloc(sizeof(char) * need_length))
}

并且这两次动态分配的内存是不连续的,导致的问题就是需要对结构体和数据字段分别进行内存管理(申请和释放)。

想要完美解决这个问题,柔性数组就出场了!

// 使用柔性数组
struct Buffer {
    int len; 
    char data[];
};

// 为带有柔性数组成员的结构体动态分配内存
buf = (struct Buffer *)malloc(sizeof(struct Buffer) + sizeof(char) * need_length);

总的来说,柔性数组比指针的优势在于:

  • 更方便管理内存,且减少一次内存分配,提升性能。
  • 减少内存碎片化。因为结构体的柔性数组和结构体成员的地址是连续的,即可一同申请内存。

goto 语句

goto 语句是一种无条件流程跳转语句,通常 goto 语句与 if 语句结合使用,当满足一定条件时,程序流程跳转到指定标签处。

// 使用goto语句实现循环
int main(){
    printf("main... \n");

    int i = 0;
    start:
        printf("gogogo...\n");
        i++;
        if (i<100){
            goto start;
        }
        
	printf("end... \n");
    return 0;
}

定义标签的语法格式:

标签: 语句;

关注公众号:编程之路从0到1

编程之路从0到1

评论

公众号:编程之路从0到1

公众号

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×