目录
-
sizeof关键字
sizeof 为C语言的一个主要关键字,而并非是一个函数,虽然其后经常会跟着一对括号,这就导致许多人认为这是一个函数,进而产生误解。
-
主要功能
求某一特定的变量、指针、结构体、枚举、联合体等所占内存空间的大小。
-
常见用法
-
与基本数据类型的相关的内存空间大小的求解
sizeof(short) = ?
sizeof(int) = ?
sizeof(float) = ?
sizeof(double) = ?
sizeof(char) = ?
这些基本数类sizeof所求的内存空间大小受到不同系统的约束。例如:在64位系统下,其大小分别为:
sizeof(char) = 1
sizeof(short) = 2
sizeof(int) = 4
sizeof(float) = 4
sizeof(double) = 8
-
与数组相关的内存空间大小的求解
int arr[64] = {0};
sizeof(arr) = ?
sizeof(arr[0]) = ?
sizeof(arr[64]) = ?
sizeof(&arr) = ?
sizeof(&arr[0]) = ?
int func (int arr[])
{
sizeof(arr) = ?
sizeof(&arr) = ?
}
-
在数组的定义处
- sizeof(arr) = 256, 是求数组的实际大小,即为 64 * 4 = 256
- sizeof(arr[0]) = 4 ,是求数组的第一个元素所占内存空间的大小,即和其定义时候的数据类型有关,这里为int 即为4字节,若为char即为1个字节依次类推。
- sizeof(arr[64]) = 4,与sizeof(arr[0])类似;
- sizeof(&arr),则是求&arr所占内存空间的大小,即求一个指针所占内存空间的大小,会与系统是64位还是32位有关;若为64位系统,则其大小位8字节,若为32位系统,则其大小位4字节 。
- sizeof(&arr[0])与sizeof(&arr)类似,都是求解一个指针所占内存空间的大小;
-
在具体函数的中
- sizeof(arr) = 8,因为在函数传参的时候数组实参会当指针形参来处理,即所传的只是数组的首地址,所以sizeof(arr)的大小会与系统的位数有关;
- 其他的sizeof的相关求解不发生变化,例如sizeof(&arr) = 8;
-
运行实例
***********in arr:********** sizeof(arr) = 256 sizeof(&arr) = 8 sizeof(&arr[0]) = 8 sizeof(arr[64]) = 4 sizeof(arr[0]) = 4 *********in function:************** sizeof(arr) = 8 sizeof(&arr[0]) = 8
-
与指针的相关的变量所占内存空间大小的求解
int p_int = NULL;
sizeof(p_int) = ?
sizeof(*p_int) = ?
- sizeof(p_int) 只要是指针其用sizeof来求某个指针变量所占内存空间的大小都与系统的位数有关,若为64位,则其大小永远位8字节;若为32位,则其大小永远为4字节。
- sizeof(*p_int) = 4,指针前加*表示取指针所指向的那段内存存放的值,即*p_int为int类型,所以其大小为4字节;
-
运行实例
sizeof(p_int) = 8 sizeof(*p_int) = 4
-
与结构体相关的变量所占内存空间大小的求解
typedef struct student
{
char name[64];
int age;
unsigned int id;
char sex;
}student_t;
typedef struct zero
{
char name[64];
int age;
unsigned int id;
char sex;
}zero_t;
void test()
{
student_t st_student;
printf("sizeof(st_student) = %ld\n", sizeof(st_student));
zero_t st_aero;
printf("sizeof(st_zero) = %ld\n", sizeof(st_zero));
}
- sizeof(st_student)的大小为多少呢? 是73?还是76?答案显然不是73。因为结果体会有字节对齐。正确答案为76
- 结构体对齐的概念:即以结构体成员中占内存最多的数据类型所占的字节数为标准,所有的成员在分配内存时都要与这个长度对齐。我们以上面这个程序为例,结构体变量 student 的成员中占内存最多的数据类型是 int 型,其占 4 字节的内存空间,那么所有成员在分配内存时都要与 4 字节的长度对齐。也就是说,虽然 char 只占 1 字节,但是为了与 4 字节的长度对齐,它后面的 3 字节都会空着。所以其大小都会4的整数倍。
- 如果我们定义一个空的结构体。那么其大小会是多少呢? 0? 1? 还是其他?我们会理所当然认为他的值应该是0,但是很可惜他不是0,而是1。但是我在Ubuntu的gcc的编译器下测试结果为0,在vc下测试结果为1,也许他还会和编译的实现相关吧。还有些编译器如果你定义一个空的结构体他会不干,抛错。
- #pragma pack(x)我们也可以是#pragma pack(x)来改变结构体对齐的字节。例如:
#pragma pack (1) typedef struct student { char name[64]; int age; unsigned int id; char sex; }student_t; void test() { student_t st_student; printf("sizeof(st_student) = %ld\n", sizeof(st_student)); }
- 其输出值为 :
sizeof(st_student) = 73
-
运行实例
sizeof(st_student) = 76
sizeof(st_zero) = 0
-
与枚举相关的变量所占内存空间大小的求解
enum color
{
RED,
BLUE,
YELLOW
}en_color;
void test()
{
printf("sizeof(en_color) = %ld\n", sizeof(en_color));
}
- sizeof(en_color) ==> sizeof(int),永远为4,不管其内部有多少变量。枚举类型,指一个被命名的整型常数的集合。即枚举类型,本质上是一组常数的集合体,只是这些常数有各自的命名。枚举类型,是一种用户自定义数据类型。枚举变量,由枚举类型定义的变量。枚举变量的大小,即枚举类型所占内存的大小。由于枚举变量的赋值,一次只能存放枚举结构中的某个常数。所以枚举变量的大小,实质是常数所占内存空间的大小(常数为int类型,当前主流的编译器中一般是32位机器和64位机器中int型都是4个字节),枚举类型所占内存大小也是这样。
-
运行实例
sizeof(en_color) = 4
-
与联合体(union)相关的变量所占内存空间大小的求解
union { int age; char name[64]; char sex; }un_student; void test() { printf("sizeof(un_student) = %ld\n", sizeof(un_student)); }
- sizeof(un_student) = 64,因为联合体的大小为其中定义的最大变量的大小。
-
运行实例
sizeof(un_student) = 64