在 C 语言中,sizeof
是一个 运算符(而不是函数),用于获取一个变量或数据类型所占用的内存字节数。它在编译时就会被计算,因此是一个 编译时常量,不会在程序运行时产生开销。
基本语法:
sizeof(expression)
- expression:可以是任何类型的变量、数据类型、数组、结构体等。
- 返回值:
sizeof
返回的是size_t
类型(通常是unsigned int
或unsigned long
),表示所占字节数。
常见用法:
-
用于基本数据类型:
- 例如:
sizeof(int)
、sizeof(double)
等。 - 返回的是该数据类型在内存中占用的字节数。
printf("sizeof(int) = %zu\n", sizeof(int)); // 输出 int 类型的大小,通常是 4 字节 printf("sizeof(double) = %zu\n", sizeof(double)); // 输出 double 类型的大小,通常是 8 字节
- 例如:
-
用于变量:
sizeof
也可以用于已声明的变量,返回该变量类型所占的字节数。
int a = 5; double b = 3.14; printf("sizeof(a) = %zu\n", sizeof(a)); // 输出 a 变量的大小,通常是 4 字节 printf("sizeof(b) = %zu\n", sizeof(b)); // 输出 b 变量的大小,通常是 8 字节
-
用于数组:
sizeof
计算数组的总字节数,而不仅仅是元素个数。- 数组的大小是:
sizeof(数组)
=元素个数 * 单个元素大小
int arr[10]; printf("sizeof(arr) = %zu\n", sizeof(arr)); // 输出数组的总大小,通常是 40 字节(10 * 4 字节) printf("sizeof(arr[0]) = %zu\n", sizeof(arr[0])); // 输出单个元素大小,通常是 4 字节
- 如果想知道数组的元素个数,可以通过以下方式:
int arr[10]; printf("Number of elements in arr: %zu\n", sizeof(arr) / sizeof(arr[0]));
-
用于指针:
sizeof
计算的是指针本身的大小,而不是指针所指向的数据类型的大小。- 指针的大小通常是固定的,取决于系统架构(例如,在 64 位系统上,指针通常占用 8 字节,在 32 位系统上,占用 4 字节)。
int *p; printf("sizeof(p) = %zu\n", sizeof(p)); // 输出指针的大小,通常是 8 字节(在 64 位系统上)
- 注意:指针的大小与它所指向的数据类型无关,指针总是占用固定的字节数。
-
用于结构体:
sizeof
可以用于结构体,返回结构体的总字节数(包括填充字节)。
struct Person { char name[20]; int age; }; printf("sizeof(struct Person) = %zu\n", sizeof(struct Person));
- 注意:结构体的大小可能会受到 内存对齐(padding)的影响。编译器通常会对结构体进行内存对齐,以便提高访问速度。为了保证对齐,结构体中的成员变量可能会被填充一定的字节。
-
用于动态分配的内存:
sizeof
也可以用于动态分配的内存(例如通过malloc
或calloc
分配的内存)。
int *arr = (int *)malloc(10 * sizeof(int)); // 分配 10 个 int 元素的内存 printf("sizeof(arr) = %zu\n", sizeof(arr)); // 输出指针的大小 free(arr);
- 注意:
sizeof(arr)
输出的是指针的大小,而不是指向的内存块的大小。
几个例子和解释:
-
基本数据类型:
int a = 5; printf("sizeof(int) = %zu\n", sizeof(int)); // 结果:通常是 4 字节 printf("sizeof(a) = %zu\n", sizeof(a)); // 结果:通常是 4 字节
-
数组:
int arr[5] = {1, 2, 3, 4, 5}; printf("sizeof(arr) = %zu\n", sizeof(arr)); // 结果:20 字节 (5 * 4 字节) printf("sizeof(arr[0]) = %zu\n", sizeof(arr[0])); // 结果:4 字节 printf("Number of elements in arr = %zu\n", sizeof(arr) / sizeof(arr[0])); // 结果:5
-
结构体:
struct Person { char name[20]; int age; }; printf("sizeof(struct Person) = %zu\n", sizeof(struct Person)); // 结果:通常是 24 字节
- 结构体中,
char
类型通常占 1 字节,而int
类型占 4 字节。为了满足内存对齐要求,编译器可能会在结构体中插入填充字节。假设int
类型变量的对齐要求是 4 字节,char
数组的 20 字节之后,会有 3 字节的填充字节,最终结构体总大小是 24 字节。
- 结构体中,
-
指针:
int *p; printf("sizeof(p) = %zu\n", sizeof(p)); // 结果:通常是 8 字节(64 位系统上)
注意事项:
sizeof
计算的是类型的大小,而不是变量的值。例如,sizeof(a)
计算的是a
变量类型所占用的字节数。sizeof
在数组的情况下会返回数组的总字节数,而不仅仅是数组的元素个数。如果需要获取元素个数,需要除以单个元素的大小。- 指针的大小是固定的,和它指向的对象无关。例如,
sizeof(int *)
返回的是指针本身占用的内存大小(在 64 位系统上通常是 8 字节)。
总结:
sizeof
是一个非常有用的运算符,常用于确定数据类型、变量、数组等所占的内存大小。- 它在编译时计算,不会产生运行时开销,是一种非常高效的工具。
- 理解
sizeof
在不同数据类型(如指针、数组、结构体)中的表现对于 C 语言编程非常重要。