[
![]() |
sizeof是C语言中的关键字,返回的结果是无符号整型常量size_t。
1)sizeof在编译期完成,我们应该把sizeof(xxx)看成一个size_t的常量,其中xxx的运算应完全忽略。如:
同样,可以给一个函数让sizeof运算,如:
2)对数组的sizeof。n个元素数组的大小是一个元素大小的n倍,常用sizeof(arr)/sizeof(arr[0])计算一个数组的长度(而且大家尽可放心编译器直接将其优化为一个整数,而不是两个整数的除运算)
3)对结构的sizeof,有两个影响因素: 结构中的元素的最大长度M,编译器的对齐设置N。
规则一:编译器对齐属性为N(1, 2, 4, 8, 16)字节(VC中用#pragma pack(N), 或者/ZpN,默认/Zp8)
规则二:当N大于元素最大长度M时,以M为准计算
另外,经过在VS2005上的尝试,对于#pragma pack(N),N为其他异常值的情况下(3, 5, 6, 7, -1, "xxx", 1.3....),以M为准
来给大家出一道考试题目,请写出输出结果:
int i = sizeof('a');
printf("%d", i);
我就不给出答案了(提示:用C和CPP作为文件后缀分别试试)
大家觉得没有问题的话再来几道:
int i = sizeof("a");
printf("%d", i);
int i = sizeof("a" + 1);
printf("%d", i);
... 未完 ...
<转载请注明出处>
Reference:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/_pluslang_sizeof_operator.asp
1)sizeof在编译期完成,我们应该把sizeof(xxx)看成一个size_t的常量,其中xxx的运算应完全忽略。如:
char i = 1;
int j = sizeof(i++);
int k = sizeof(i+0.1);
printf("%d %d %d", i, j, k); // 输出为 1 1 8,因为i++并不真正计算,sizeof只关心输入的数据类型,i+0.1被提升为double
int j = sizeof(i++);
int k = sizeof(i+0.1);
printf("%d %d %d", i, j, k); // 输出为 1 1 8,因为i++并不真正计算,sizeof只关心输入的数据类型,i+0.1被提升为double
同样,可以给一个函数让sizeof运算,如:
double ft(int *i) {
(*i)++;
return (*i) * 3.14;
}
void main()
{
int i = 1;
int j = sizeof(ft(&i));
printf("%d %d", j, i); // 输出为 8 1,因为ft()并没有运算,sizeof只关心ft()的返回类型是double(8)
}
(*i)++;
return (*i) * 3.14;
}
void main()
{
int i = 1;
int j = sizeof(ft(&i));
printf("%d %d", j, i); // 输出为 8 1,因为ft()并没有运算,sizeof只关心ft()的返回类型是double(8)
}
2)对数组的sizeof。n个元素数组的大小是一个元素大小的n倍,常用sizeof(arr)/sizeof(arr[0])计算一个数组的长度(而且大家尽可放心编译器直接将其优化为一个整数,而不是两个整数的除运算)
3)对结构的sizeof,有两个影响因素: 结构中的元素的最大长度M,编译器的对齐设置N。
规则一:编译器对齐属性为N(1, 2, 4, 8, 16)字节(VC中用#pragma pack(N), 或者/ZpN,默认/Zp8)
规则二:当N大于元素最大长度M时,以M为准计算
#pragma pack(1)
struct {
char a;
char b;
int c;
double d;
char *e;
} str_a;
printf("%d", sizeof(str_a)); // 输出为18, a:1,b:1, c:4, d:8, e:4,最小单位1
struct {
char a;
char b;
int c;
double d;
char *e;
} str_a;
printf("%d", sizeof(str_a)); // 输出为18, a:1,b:1, c:4, d:8, e:4,最小单位1
#pragma pack(4)
struct {
char a;
char b;
int c;
double d;
char *e;
} str_a;
printf("%d", sizeof(str_a)); // 输出为20, ab:4, c:4, d:8, e:4,最小单位4
struct {
char a;
char b;
int c;
double d;
char *e;
} str_a;
printf("%d", sizeof(str_a)); // 输出为20, ab:4, c:4, d:8, e:4,最小单位4
#pragma pack(16)
struct {
char a;
char b;
int c;
double d;
char *e;
} str_a;
printf("%d", sizeof(str_a)); // 输出为24, abc:8, d:8, e:8,最小单位8(因为8<16,以8为准)
struct {
char a;
char b;
int c;
double d;
char *e;
} str_a;
printf("%d", sizeof(str_a)); // 输出为24, abc:8, d:8, e:8,最小单位8(因为8<16,以8为准)
另外,经过在VS2005上的尝试,对于#pragma pack(N),N为其他异常值的情况下(3, 5, 6, 7, -1, "xxx", 1.3....),以M为准
来给大家出一道考试题目,请写出输出结果:
int i = sizeof('a');
printf("%d", i);
我就不给出答案了(提示:用C和CPP作为文件后缀分别试试)
大家觉得没有问题的话再来几道:
int i = sizeof("a");
printf("%d", i);
int i = sizeof("a" + 1);
printf("%d", i);
... 未完 ...
<转载请注明出处>
Reference:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/_pluslang_sizeof_operator.asp
在遇到sizeof(\"abcabc\" + 1)的时候,答案是7
当然gcc都是4
我说明的意思是在运行期完全忽略,复引用运算符也是在编译期可以决定的,所以决定以后sizeof就是一个size_t的常量,里面的xxx内容就会被忽略。
1. 计算空间大小, 最常见的是malloc的参数,例如:
data_type_t *p = (data_type_t *)malloc(sizeof(*p));
2. 遍历数组时计算元素个数, 比如
#define _dim(arr) sizeof(arr)/sizeof(*(arr))
int i;
int iarr[] = &leftsign;1, 2, 3&rightsign;;
for (i = 0; i < _dim(iarr); i++) &leftsign;...&rightsign;
对于\"其中xxx的运算应完全忽略\"的说法,并不准确, 比如在上述用法1中,就使用了复引用运算符,而这会影响sizeof的计算结果,其关键原因在与这样的计算是否会影响sizeof的操作数的类型。比如int i; sizeof(i)和sizeof(i++)的结果是一样的,其原因是它们的结果都是sizeof(int),而在例子中sizeof(p)和sizeof(*p)不一定相同是因为sizeof(p)的结果是sizeof(data_type_t *)而sizeof(*p)的结果是sizeof(data_type_t)。
我的建议是,除了使用复引用运算符外,不要在sizeof的操作数中使用其他运算符,在实际应用中,我也从来没有遇到过需要使用其他运算符的情形。
sizeof运算符的结果的本质是编译器为某类型分配了多少空间,该值以字节为单位。例如:
void foo(void) &leftsign;int arr[3]; printf(\"foo sizeof(arr) = %d\n\", sizeof(arr)); bar(arr); &rightsign;
void bar(int arr[3]) &leftsign; printf(\"bar sizeof(arr) = %d\n\", sizeof(arr)); &rightsign;
在foo中,arr的类型为int[3],在bar中arr的类型为int *, 在参数列表中写作int arr[xxx], int[]和int *的完全等效的,C运行时只会传递foo中长度为3*sizeof(int)的arr的起始位置给bar做为参数,它将占据sizeof(int *)的空间。
请记住最根本的原因和最基本的用法,请避免可能让人迷惑的用法, 比如sizeof('a'),你一眼看出'a'是一个char类型还是一个int类型吗? 或是sizeof(\"a\"), 你在不查阅任何编程手册的情况下马上回答出\"a\"会被当作一个char *类型还是一个char [2]类型么? 如果你不能, 请不要这样用。记住,在任何时候,都应该使用最直接的表达法。
查资料就要看权威的
转自水木清华 career_ms区
// 输出为24, abc:8, c:4, d:8, e:8,最小
应为:
// 输出为24, abc:8, d:8, e:8,最小