sizeof 运算符是 C 的内置运算符, 作用于一个具体的标识符或一个数据类型关键字, 返回以字节表示的该运算对象占用的内存空间.
作用于具体的标识符时可以不加括号, 作用于数据类型关键字时必须加括号.
C 标准只规定 sizeof 返回一个无符号整型, 在不同的实现中可能是 unsigned int 或 unsigned long 类型, 因此用 printf() 输出时对应的转换说明可能是 %ud 或 %lu, 要根据具体实现来定, 这严重影响了编程效率和代码的可移植性.
C 提供了可移植性更好的 size_t 类型作为 sizeof 的返回值类型. size_t 不是一个新的类型, 而是使用 typedef 机制定义的类型. 在头文件 stddef.h (在包含 stdio.h 头文件时已将其包含在其中)中, 把 size_t 定义为 sizeof 的返回值类型, 这被称为底层类型 (underlying type), 同时规定 printf() 使用 z 修饰符表示打印 size_t 类型.
头文件中使用 typedef 将 size_t 作为 unsigned int 或 unsigned long 的别名. 在使用 size_t 时编译器会自动根据不同系统进行替换.
C99 新增 %zd 作为 printf() 显示 size_t 类型的值, 如果不支持可以用 %u 或 %lu. 具体是换成哪一种应根据具体的实现来确定.
整个 sizeof 表达式被视为整型常量.
程序示例:
// sizeof的一个示例
#include<stdio.h>
#include<string.h>
#define GREET "hello"
int main(void)
{
char name[10];
printf("Enter your name: ");
scanf("%s" , name); // 给字符数组赋值
printf("Your name is %s.\n" , name); // 输出字符数组
printf("name array occupies %zd bytes.\n", sizeof name); // 打印字符数组占用的字节数
printf("name string has %zd characters.\n" , strlen(name)); // 打印字符串所含有的字符个数, 不包括最后的空字符, strlen()函数的返回值也用%zd作为转换说明
printf("GREET string has %zd characters.\n" , strlen(GREET)); // strlen()不包括最后的空字符
printf("GREET string occupies %zd bytes.\n" , sizeof(GREET)); // sizeof计算所有的字节数,所以包括字符串最后的空字符
return 0;
}
结果:
Enter your name: coldbug
Your name is coldbug.
name array occupies 10 bytes.
name string has 7 characters.
GREET string has 5 characters.
GREET string occupies 6 bytes.
程序示例:
// sizeof的一个示例
size_t int_size; // 定义一个size_t类型的变量
int_size = sizeof(int);
printf("int has %zd bytes.\n" , int_size); // 打印一个size_t类型的变量
结果:
int has 4 bytes.
程序示例;
// 打印一些数据类型的长度
#include<stdio.h>
#include<complex.h>
#include<limits.h>
#include<float.h>
int main(void)
{
printf("以字节为单位,打印一些数据类型的长度:\n");
putchar('\n');
printf("_Bool: %zd\n" , sizeof(_Bool));
putchar('\n');
int * p;
printf("int * : %zd\n" , sizeof(p));
printf("char * : %zd\n" , sizeof(char *));
printf("指针变量本身占用%zd个字节\n" , sizeof(p));
putchar('\n');
printf("char: %zd\n" , sizeof(char));
printf("int: %zd\n" , sizeof(int));
printf("short: %zd\n" , sizeof(short));
printf("long: %zd\n" , sizeof(long));
printf("long long: %zd\n" , sizeof(long long));
putchar('\n');
printf("unsigned char: %zd\n" , sizeof(unsigned char));
printf("unsigned int: %zd\n" , sizeof(unsigned int));
printf("unsigned short: %zd\n" , sizeof(unsigned short));
printf("unsigned long: %zd\n" , sizeof(unsigned long));
printf("unsigned long long: %zd\n" , sizeof(unsigned long long));
printf("有符号和无符号占用的字节数是不变的.\n");
putchar('\n');
printf("float: %zd\n" , sizeof(float));
printf("double: %zd\n" , sizeof(double));
printf("long double: %zd\n" , sizeof(long double));
putchar('\n');
printf("float complex: %zd\n" , sizeof(float complex));
printf("double complex: %zd\n" , sizeof(double complex));
printf("long double complex: %zd\n" , sizeof(long double complex));
putchar('\n');
// printf("float imaginary: %zd\n" , sizeof(float imaginary));
// printf("double imaginary: %zd\n" , sizeof(double imaginary));
// printf("long double imaginary: %zd\n" , sizeof(long double imaginary));
putchar('\n');
printf("int max = %d\n" , INT_MAX);
printf("int min = %d\n" , INT_MIN);
putchar('\n');
printf("float max = %f\n" , FLT_MAX);
putchar('\n');
return 0;
}
结果:
以字节为单位,打印一些数据类型的长度:
_Bool: 1
int * : 8
char * : 8
指针变量本身占用8个字节
char: 1
int: 4
short: 2
long: 4
long long: 8
unsigned char: 1
unsigned int: 4
unsigned short: 2
unsigned long: 4
unsigned long long: 8
有符号和无符号占用的字节数是不变的.
float: 4
double: 8
long double: 16
float complex: 8
double complex: 16
long double complex: 32
int max = 2147483647
int min = -2147483648
float max = 340282346638528860000000000000000000000.000000
sizeof 内的表达式不进行计算。代码示例:
#include<stdio.h>
int main(void)
{
short a = 0;
int b = 10;
printf("%d\n", sizeof(a = a + b));
printf("%d\n", sizeof(short));
printf("%d\n", sizeof(int));
printf("%d\n", a);
return 0;
}
结果:
2
2
4
0
一个表达式有两个属性, 即类型属性和值属性, 类型属性可以推算出来, 不一定非要求值.