//By Richard
#include <stdio.h>
#include <string.h>
char foo()
{
printf("foo() has benn called.\n");
return 'a';
}
int foo1()
{
printf("foo1() has benn called.\n");
return 0;
}
int foo2(char a2[2])
{
int a=sizeof(a2);
return a;
}
int foo3(char a3[])
{
int a=sizeof(a3);
return a;
}
struct S1
{
char c;
int i;
};
struct S2
{
int i;
char c;
};
struct S3
{
char c1;
S1 s;
char c2;
};
union U
{
int i;
char c;
S1 s;
};
int main()
{
//一、基本数据类型
printf("sizeof(int) is : %d\n",sizeof(int));//4
printf("sizeof(unsigned int) is : %d\n",sizeof(unsigned int));//4
printf("sizeof(short) is : %d\n",sizeof(short));//2
printf("sizeof(unsigned short) is : %d\n",sizeof(unsigned short));//2
printf("sizeof(long) is : %d\n",sizeof(long));//4
printf("sizeof(unsigned long) is : %d\n",sizeof(unsigned long));//4
printf("----------------------------\n");
printf("sizeof(char) is : %d\n",sizeof(char));//1
printf("sizeof(unsigned char) is : %d\n",sizeof(unsigned char));//1
printf("----------------------------\n");
printf("sizeof(float) is : %d\n",sizeof(float));//4
printf("sizeof(double) is : %d\n",sizeof(double));//8
printf("sizeof(long double) is : %d\n",sizeof(long double));//8
printf("----------------------------\n");
//typedef unsigned int size_t;
printf("sizeof(size_t) is: %d\n",sizeof(size_t));//4
printf("----------------------------\n");
printf("sizeof(2) is: %d\n",sizeof(2));//4
printf("sizeof(2+3.14) is: %d\n",sizeof(2+3.14));//8
printf("----------------------------\n");
//二、sizeof可以对一个函数调用求值,其结果是函数返回类型的大小
//函数并不会被调用
printf("sizeof(foo()) (return 'a') is: %d\n",sizeof(foo()));//1
printf("sizeof(foo1()) (return 0) is: %d\n",sizeof(foo1()));//4
printf("----------------------------\n");
//三、sizeof的常量性
//sizeof的计算发生在编译时刻,所以可以被当做常量表达式使用
//比如说,定义数组 char ary[sizeof(int)*10];
//四、指针变量的sizeof
//在32位计算机中,一个指针变量的返回值必定是4(个字节)
//原因:指针记录了另一个对象的地址,等于计算机内部地址总线的长度
//64位系统中指针变量的sizeof结果为8
//测试指针所用变量
char *pc="abc";
int *pi;
//string *ps;
char **ppc=&pc;
void (*pf)();//函数指针
printf("sizeof(pc) is: %d\n",sizeof(pc));//4
printf("sizeof(pi) is: %d\n",sizeof(pi));//4
//printf("sizeof(ps) is: %d\n",sizeof(ps));//4
printf("sizeof(ppc) is: %d\n",sizeof(ppc));//4
printf("sizeof(pf) is: %d\n",sizeof(pf));//4
printf("----------------------------\n");
//五、数组的sizeof
char a1[]="abc";
int a2[3];
printf("sizeof(a1) is: %d\n",sizeof(a1));//4,原因:a1有4个字符(包括'\0'),每个字符占一个字节
printf("sizeof(a2) is: %d\n",sizeof(a2));//12,原因:a2有3个int型数字,每个int型站4个字节
printf("----------------------------\n");
//求数组元素的个数
int c1=sizeof(a1)/sizeof(char);
int c2=sizeof(a2)/sizeof(int);
printf("c1 is: %d\n",c1);//4
printf("c2 is: %d\n",c2);//3
printf("----------------------------\n");
//六
/*函数在上面已经定义,写在这里只是为了看起来方便
int foo2(char a2[2])
{
int a=sizeof(a2);
return a;
}
int foo3(char a3[])
{
int a=sizeof(a3);
return a;
}
*/
char aa2[2];
char aa3[]="hello";
printf("The value of foo2() is : %d\n",foo2(aa2));//4
printf("The value of foo3() is : %d\n",foo3(aa3));//4
printf("----------------------------\n");
//为什么都是4哦?
//这里函数参数aa2、aa3已不再是数组类型,而是蜕变成指针,相当于char *aa2
//我们调用函数foo2时,程序会在栈上分配一个大小为3的数组吗?不会!数组是“传址”的,
//调用者只需将实参的地址传递过去即可,所以aa2和aa3自然为指针类型(char*),a的值也就为4
//即一个指针所占的字节数,为4
//七、结构体的sizeof
/*
struct S1
{
char c;
int i;
};
struct S2
{
int i;
char c;
};
struct S3
{
char c1;
S1 s;
char c2;
};
*/
S1 s1={'A',1};
S2 s2={1,'A'};
S3 s3={'A',s1,'B'};
printf("sizeof(s1) is :%d\n",sizeof(s1));//8
printf("sizeof(s2) is :%d\n",sizeof(s2));//8
printf("sizeof(s3) is :%d\n",sizeof(s3));//16
printf("----------------------------\n");
/*************************************************************************
*1,字节对齐的细节和编译器实现相关,但一般而言,满足三个准则:
*(1)结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
*(2)结构体每个成员相对于结构体首地址的【偏移量】(offset)都是成员大小的整数倍,
* 如有需要编译器会在成员之间加上填充字节(internal padding);
*(3)结构体的【总大小】为结构体最宽基本类型成员大小的整数倍,
* 如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。
*****(3个我们判断的依据,第一个准则可以不用考虑,因为编译器已经实现了)*****
*2,调试程序,查看s1和s2的内存分布
* s1:41 cc cc cc 01 00 00 00
* s2:01 00 00 00 41 cc cc cc
* cc为填充字符,16进制的41为65,即为'A',01表示1
* s1中,int型占4个字节,偏移量得从4开始,所以前面得填充字节
* s2中,总大小不可能为5个字节,只能为4的倍数,为8,后面得填充字节
* (成员大小指char定义的成员或int定义的成员)
*3,分析S3(复合型)
* s3:41 cc cc cc|41 cc cc cc|01 00 00 00|42 cc cc cc
* 'A' s1{'A',1} 'B'
* S1的最宽简单成员的类型为int,S3在考虑最宽简单类型成员时是将S1“打散”看的,
* 所以S3的最宽简单类型为int,这样,通过S3定义的变量,其存储空间首地址需要被4整除,
* 整个sizeof(S3)的值也应该被4整除。
* s1偏移量为4,占8个字节
* c2的偏移量为12,但总字节数得是4的倍数,所以后面补充字节,共为16个字节
************************************************************************/
//八、联合体的sizeof
/*
union U
{
int i;
char c;
S1 s;
};
*/
printf("sizeof(U) is : %d\n",sizeof(U));//8
//结构体在内存组织上是顺序式的,联合体则是重叠式,各成员共享一段内存,
//所以整个联合体的sizeof也就是每个成员sizeof的最大值,为8
return 0;
}
sizeof详细解读
最新推荐文章于 2024-01-30 20:52:46 发布