本文已参与「新人创作礼」活动,一起开启掘金创作之路。
字节对齐 、pragma 、位域长度问题整理
- 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
- 结构体每个成员相对结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节;
- 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节。
#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;只能被初始化一次 修饰全局变量,仅当前文件可以使用 修饰函数,仅当前文件可以使用