C语言基础整理

129 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

字节对齐 、pragma 、位域长度问题整理

  1. 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
  2. 结构体每个成员相对结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节;
  3. 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节。
#include <stdio.h>
// 按结构体最宽数据类型int对齐
// char[*]多少都是按4字节对齐
struct stChar{
        char a[5];
        int b;
        char c;
};

// 按结构体最宽数据类型short对齐
struct stShort{
        char a;
        short b;
};

// 按结构体最宽数据类型long对齐
struct stLong{
        char a;
        long b;
};

// 按结构体最宽数据类型int对齐
// 变量c的偏移量 要为自己大小的倍数
#pragma pack(8) //为2时,sizeof为10.为8时sizeof为12 
struct AA
{
        int a;  
        char b; 
        short c; //长度2 偏移量要提升到2的倍数6;存放位置区间[6,7]
        char d; 
};

struct AAA
{
        // 类型说明符 位域名: 位域长度
        int a:2; //变量a,4位长度,只使用两位长度 sizeof(AAA)为4
        char b:1;
};

int main()
{
        struct stChar stChar1;
        struct stShort stShort1;
        struct stLong stLong1;
        struct AA stAA;
        struct AAA stAAA;

        printf("stChar = [%ld]\n", sizeof(stChar1));
        printf("stShort = [%ld]\n", sizeof(stShort1));
        printf("stLong = [%ld]\n", sizeof(stLong1));
        printf("stAA = [%ld]\n", sizeof(stAA));
        printf("stAAA = [%ld]\n", sizeof(stAAA));
        return 0;
}

打印结果

stChar = [16]
stShort = [4]
stLong = [16]
stAA = [12]
stAAA = [4]

很久之前写的C语言基础,覆盖范围不是很全,发出来请大家指导,包含const、extern、static的使用方法,和使用场景。

const

const 修饰变量 表示变量为常量,不可修改 const int a =1; int const a =1; 相同含义,都表示n为常量不可修改。 a = 2 报错 const char c[10] = "123"; 定义之后不能改变。c[0] ='3' 报错。

const int *a; 常量指针 变量不可修改 const char *str;字符串不能修改 str[2] = 1报错 int * const a;指针常量 指针不能修改 char *const str;指针不能修改 str= p 报错

修饰函数参数,和修饰变量,基本没区别 fun(char *str1, const char *str2, char * const str3)
str2字符串在函数内不可修改,str3指针不能修改 str2[0] = '0' 报错 str3=p 报错

extern

引用其它文件的变量或者函数,或者本文件中未定义的全局变量。(在变量使用之后定义的全局变量,也是给网上看到的使用方法)

static

修饰局部变量,函数内static int a =10;只能被初始化一次 修饰全局变量,仅当前文件可以使用 修饰函数,仅当前文件可以使用