sizeof in C

之前一直不在意这个东西,今天突然想起来了了一个问题.

经过百度和自己的测试发现,原来自己还有很多都不会.所以记录下来.毕竟细节决定成败!

学过数据结构的应该知道指针是一个很重要的概念,它记录了另一个对象的地址。

既然是来存放地址的,那么它当然等于计算机内部地址总线的宽度。

所以在32位编译器中,一个指针变量的返回值必定是4bytes,

但是,在64位编译器中指针变量的sizeof结果为8bytes。

指针变量的sizeof值与指针所指的对象没有任何关系

数组的sizeof值等于数组所占用的内存字节数

    char a[] = {1, 2, 3};
    printf("%lu\n",sizeof(a));//3

    char aa[] = "ab";
    printf("%lu\n",sizeof(aa));//3

    int b[] = {1, 2, 3};
    printf("%lu\n",sizeof(b));//12

    char *pa = "ab";
    printf("%lu\n",sizeof(pa));//8

    int *pi = b;
    printf("%lu\n",sizeof(pi));//8

    char **ppa = &pa;
    printf("%lu\n",sizeof(ppa));//8

    void (*pf)();//函数指针
    printf("%lu\n",sizeof(pf));//8

可以总结一下:sizeof如果是数组变量名称和话就是数组长度乘上基本数据类型大小.(所以第三个的值是3 * 4 = 12)

sizeof如果是指针的话,64位编译器都是8bytes,32位编译器都是4bytes.

这里为什么要说是编译器呢,因为字节的大小其实不是计算机系统决定的,其实是编译器决定的.

具体可以看我之前写的博客:The different of bit Compiler

那么看下面两种情况:

void fp(int buffer[3]) {
    printf("%lu\n",sizeof(buffer));//8
}
void fp1(int buffer[]) {
    printf("%lu\n",sizeof(buffer));//8
}

输出结果都是8,因为是地址传递,传的都是指针.所以在64位编译器中都是8

当我们用sizeof计算数组长度的时候正确的写法是这样:

    printf("%lu\n",sizeof(a)/sizeof(char));//总长度/单个元素的长度  char型

    printf("%lu\n",sizeof(b)/sizeof(b[0]));//总长度/第一个元素的长度 int型

结构体:

对于这两个结构体一样么?

struct s1 {
    char a;
    int b;
    char c;
};
struct s2 {
    char a;
    char c;
    int b;
};

看着一样,其实不一样.(有的人会觉得这两个结构体在内存中不都是占用6个字节么 4+1+1 = 6不就是变量位置换了一下么?)其实都不对

    struct s1 s1 = { ‘a‘, 0xFFFFFFFF, ‘b‘ };
    printf("%lu\n",sizeof(s1));//12

    struct s2 s2 = { ‘a‘, ‘b‘, 0xFFFFFFFF };
    printf("%lu\n",sizeof(s2));//8

一个占用12个字节的内存,一个占用8字节的内存!!!这仅仅就同一个变量换了一个位置而已.

解释:这就涉及到计算机组成原理的知识了.

我们先设置指针指向s1和s2

    struct s1 *sp1 = &s1;
    printf("%lu\n",sizeof(sp1));//8

    struct s2 *sp2 = &s2;
    printf("%lu\n",sizeof(sp2));//8

设置断点,lldb分别输入x/8xh sp1和x/8xh sp2,显示结果如下.

可以看到显示不一样.对于第一个结构体sp1:占用了12个字节的位置.a后面占用了3个字节是空的.b后面的三个字节是空的.大大浪费了存储空间

再看看sp2:占用了8个字节,但是有些人会问,这后面为什么不是0呢?

sp2的内存地址是0x7fff5fbff868,而sp1是0x7fff5fbff870,其实sp2后面跟着的就是sp1的内存的地址值...

大家也许会问为什么要这样,计算机组成原理告诉我们这叫字节对齐,有助于加快计算机的取数速度.

现在我来解释一下x/8xh sp1的意思.

在debug模式断点处,查看字符指针变量内存中的值,现在只能查看第一个内存中的值可以在输出窗口采用gdb命令:x /nfu <addr>

n表示要显示的内存单元的个数

-----------------------------------------

f表示显示方式, 可取如下值:
x 按十六进制格式显示变量
d 按十进制格式显示变量
u 按十进制格式显示无符号整型
o 按八进制格式显示变量
t 按二进制格式显示变量
a 按十六进制格式显示变量
i 指令地址格式
c 按字符格式显示变量
f 按浮点数格式显示变量
-----------------------------------------
u表示一个地址单元的长度:
b表示单字节
h表示双字节
w表示四字节
g表示八字节
-------------------------------------------

既然上面的搞定,那么下面也是一样的.就不多解释.

struct s3 {
    char a;
    char c;
    int b;
    short d;
};
struct s4 {
    char a;
    char c;
    short d;
    int b;
};    

    struct s3 s3 = { ‘a‘, ‘b‘, 0xFFFFFFFF, 0xFFFF };
    printf("%lu\n",sizeof(s3));//12

    struct s4 s4 = { ‘a‘, ‘b‘, 0xFFFF, 0xFFFFFFFF };
    printf("%lu\n",sizeof(s4));//8

更详细的解释在百度百科:sizeof

运行环境:Xcode7, OS X 10.10

时间: 2024-07-29 18:33:53

sizeof in C的相关文章

关于malloc和sizeof的用法

问题1: 1.L.elem = (ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType)); 2.newbase = (ElemType *)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType)); 其中L是已经定义的线性表,LIST_INIT_SIZE是线性表存储空间的初始分配量,listsize是当前分配的存储容量(以sizeof(ElemType)为单位) 解释: 第一个句子:用ma

sizeof strlen strncpy

sizeof测类型(数组名除外) strlen测实际长度 strncpy返回指针类型 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 int main() 5 { 6 char *p="wangddd"; 7 printf("%d\n",sizeof(p));//输出4,指针类型 8 9 char x[8]; 10 printf("%d

关于sizeof的那些事

一 结构体 先上代码: struct A { int a; double d; char b; short c; }; 以上代码的sizeof(struct A)为24.分析: a占用4字节,由于d占用8字节,且d需要在8字节处对齐,因此a不仅有4字节存放内容,并且占另外的4个字节使得d位于8字节处.由于c需要在2字节处对齐,所以b占用了2个字节,c占用两个字节,目前总共是20字节,但是整个结构体A根据最大字节对齐,因此为8字节对齐,为了使得类型位struct A的数组的下一个元素处于正确的对齐

C++字符串使用sizeof时注意

char tmp1[20] = {"hello,你好"}; char tmp2[] = {"hello,你好"}; char *tmp3 = new char[20]; sprintf(tmp3,"%s","hello,你好"); string tmp4 = "hello,你好"; printf("%d %d %d %d\n",sizeof(tmp1),sizeof(tmp2),size

含有虚函数的类sizeof大小

#include <iostream> using namespace std; class Base1{ virtual void fun1(){} virtual void fun11(){} public: virtual ~Base1(); }; class Base2{ virtual void fun2(){} }; class DerivedFromOne: public Base2 { virtual void fun2(){} virtual void fun22(){} }

程序猿之---C语言细节24(段错误、类型提升、sizeof &#39;A&#39;)

主要内容:段错误.类型提升.sizeof  'A' #include <stdio.h> int main() { union test{ char a[10]; int b; }u; int *p = (int *)&(u.a[1]); // 没有引起总线错误 *p = 17; printf("%d\n",*p); #if 0 int *q = 0; // 引起段错误,在linux中运行可看到段错误,在windows下运行时直接出错 *q = 1; #endif

sizeof 和类继承 虚继承 求类大小

代码: #include <iostream> using namespace std; /* class a{ float k; // 4字节 virtual void foo(){} //有一个4字节的指针指向自己的虚函数表 }; class b : virtual public a{ virtual void f(){} }; 有这样的一个指针vptr_b_a,这个指针叫虚类指针,也是四个字节:还要包括类a的字节数,所以类b的字节数就求出来了. 运行结果: 8 16 */ /* clas

宽字符std::wstring的长度和大小问题?sizeof(std::wstring)是固定的32,说明std::wstring是一个普通的C++类,而且和Delphi不一样,没有负方向,因为那个需要编译器的支持

std::wstring ws=L"kkkk";    int il=ws.length();    int ia=sizeof(ws);    int ib=sizeof("dddd");    int ic=sizeof(L"kkkk");输出为    il=4,ia=32,ib=5,ic=10为什么ia=32 ?wstring到底对L"kkkk"做了什么? http://www.debugease.com/vc/2171

C++中sizeof(struct)怎么计算?(转)

struct为空时,大小为1. 1. sizeof应用在结构上的情况 请看下面的结构: 1 struct MyStruct 2 { 3 double dda1; 4 char dda; 5 int type; 6 }; 对结构MyStruct采用sizeof会出现什么结果呢?sizeof(MyStruct)为多少呢?也许你会这样求: sizeof(MyStruct)=sizeof(double) sizeof(char) sizeof(int)=13 但是当在VC中测试上面结构的大小时,你会发现

C基础题-sizeof

1.#include "stdio.h" int main() {    char str[] = "hello";    char *s = "hello";    int a[] = {3, 5, 7};    printf("%d\n%d\n%d\n", sizeof(str), sizeof(s), sizeof(a));    return 0;}//输出6, 4, 12sizeof(str)=6   str是数组,