怎么使用C/C++基础sizeof

发布时间:2021-10-29 15:48:03 作者:iii
来源:亿速云 阅读:130

本篇内容主要讲解“怎么使用C/C++基础sizeof”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么使用C/C++基础sizeof”吧!

在 C/C++ 中,sizeof() 是一个判断数据类型或者表达式长度的运算符。

1、sizeof 定义sizeof 是 C/C++ 中的一个操作符(operator),返回一个对象或者类型所占的内存字节数。

The sizeof keyword gives the amount of storage, in bytes, associated with a  variable or a type(including aggregate types). This keyword returns a value of  type size_t.

——来自MSDN

其返回值类型为 size_t ,在头文件 stddef.h 中定义为: typedef unsigned int size_t;

从sizeof 的定义可以看出:sizeof 不是一个函数,因为函数调用必须有一对括号。

#include <stdio.h>  int main(void) {    int num = 97;     printf("sizeof(num = 0)的值:%d\n",sizeof(num = 0));       printf("num 的值:%d\n",num);       return 0; }

怎么使用C/C++基础sizeof

运行结果为4,97;并不是4,0

说明:sizeof 不是标准意义上的一元操作符,不支持链式表达式,sizeof 作用域范围内的语句不会编译成机器码,如 sizeof(num++) 中的  ++ 不执行。sizeof 也不是函数, sizeof 更像一个特殊的宏,在编译阶段求值。

2、sizeof 用法sizeof 有两种语法形式,如下:

sizeof(type_name);    //sizeof(类型); sizeof (object);      //或sizeof object 都属于 sizeof对象;

所以:

int i; sizeof(i);    //合理 sizeof i;     //合理 sizeof(int);  //合理 sizeof int;   //不合理

1)基本数据类型的 sizeof

这里的基本数据类型是指short、int、long、float、double这样的简单内置数据类型。

由于它们的内存大小是和系统相关的,所以在不同的系统下取值可能不同。

#include <iostream> using namespace std;   int main() {    cout << "Size of char : " << sizeof(char) << endl;    cout << "Size of int : " << sizeof(int) << endl;    cout << "Size of short int : " << sizeof(short int) << endl;    cout << "Size of long int : " << sizeof(long int) << endl;    cout << "Size of float : " << sizeof(float) << endl;    cout << "Size of double : " << sizeof(double) << endl;    cout << "Size of wchar_t : " << sizeof(wchar_t) << endl;    return 0; }

在 32 位系统下内置数据类型与其 sizeof 运算结果如下:

Size of char : 1 Size of int : 4 Size of short int : 2 Size of long int : 4 Size of float : 4 Size of double : 8 Size of wchar_t : 4

2) 指针类型的 sizeof

指针主要用于存储地址,前几天文章C语言指针详解提到过,指针变量的位宽等于机器字长,机器字长由 CPU 寄存器位数决定。在 32  位系统中,一个指针变量的返回值为 4 字节, 64 位系统中指针变量的 sizeof 结果为 8 字节。

char *p =”hello”;  sizeof( p );       // 结果为4  sizeof(*p);        // 结果为1  int *pi;  sizeof( pi );      //结果为4  sizeof(*pi);       //结果为4  char **pp = &p;  sizeof( pp );      // 结果为4  sizeof( *pp );     // 结果为4

3) 函数类型的 sizeof

函数类型以其返回类型作为自身类型,进行 sizeof 取值。

void fun1() { } int fun2() {    return 0; } double fun3() {    return 0.0; } cout << sizeof(fun1()) << endl;  //错误!无法对void类型使用sizeof cout << sizeof(fun2()) << endl;  //fun2()返回值类型为int,输出4 cout << sizeof(fun3()) << endl;  //fun3()返回值类型为double,输出8

注意:不能对返回 void 函数和函数指针进行 sizeof 取值。

4) 数组类型的 sizeof

当 sizeof 作用于数组时,求取的是数组所有元素所占用的大小。

int A[3][5];     char c[]="abcdef";     double*(*d)[3][6];      cout<<sizeof(A)<<endl;      //输出60     cout<<sizeof(A[4])<<endl;   //输出20     cout<<sizeof(A[0][0])<<endl;//输出4     cout<<sizeof(c)<<endl;      //输出7     cout<<sizeof(d)<<endl;      //输出4     cout<<sizeof(*d)<<endl;     //输出72     cout<<sizeof(**d)<<endl;    //输出24     cout<<sizeof(***d)<<endl;   //输出4     cout<<sizeof(****d)<<endl;  //输出8

A 的数据类型是 int[3][5] ,A[4] 的数据类型是 int[5],A[0][0]数据类型是 int 。所以:

sizeof(A)==sizeof(int[3][5])==3*5*sizeof(int)==60 sizeof(A[4])==sizeof(int[5])=5*sizeof(int)==20 sizeof(A[0][0])==sizeof(int)==4

如果字符数组表示字符串,数组末自动插入 '\0',所以 c 的数据类型是 char[7] ,所以  sizeof(c)=sizeof(char[7])==7。

d 是一个很奇怪的定义,他表示一个指向 double*[3][6] 类型数组的指针。既然是指针,所以 sizeof(d) 就是4。

既然 d 是执行 double*[3][6] 类型的指针, *d 就表示一个 double*[3][6] 的多维数组类型,因此  sizeof(*a)=3*6*sizeof(double*)=72 。

**d 表示一个 double*[6] 类型的数组,所以 sizeof(**d)=6*sizeof (double*)=24。

***d 表示其中的一个元素,也就是 double* ,所以 sizeof(***d)=4 。

****d 是一个 double ,所以 sizeof(****d)=sizeof(double)=8。

当数组作为函数形参时,下面输出结果应该是多少呢?

int GetStrLength(char str[]) {    return sizeof(str); }  int main() {    char szStr[] = "abcdef";    cout<< GetStrLength() << endl;    return 0; }

输出不是 7 ,这里函数参数 str[] 已不再是数组类型,而是蜕变成指针,我们调用函数 GetStrLength() 时,程序会在栈上分配一个大小为 7  的数组吗?不会!数组是“传址”的,调用者只需将实参的地址传递过去,所以 str 自然为指针类型 (char*) ,输出值为:4 。

5) 结构体类型的 sizeof

对于 struct 数据结构由 CPU 的对齐问题导致 struct 的大小变得比较复杂。具体可以查看以前的文章一文轻松理解内存对齐。

理论上,int 占 4byte , char 占一个 byte ,那么将它们放到一个结构体中应该占 4+1=5byte  ;但是实际上,通过运行程序得到的结果是 8byte 。

#include<stdio.h>  struct{     int x;     char y; }Test;  int main() {     printf("%d\n",sizeof(Test)); // 输出8不是5     return 0; }

结构体的大小跟结构体成员对齐有密切关系,而并非简单地等于各个成员的大小之和!比如对如下结构体两个结构体 A、B 使用 sizeof  的结果分别是:16,24。可以看出 sizeof(B) 并不等于 sizeof(int)+sizeof(double)+sizeof(int)=16 。

struct A {   int num1;   int num2;   double num3; }; struct B {   int num1;   double num3;   int num2; };

结构体A和B中包含的成员都一样,只不过顺序不同而已,为什么其大小不一样呢?要解释这个问题,就要了解结构体成员对齐的规则。

从三个规则我们来看看为什么 sizeof(B) 等于 24 :首先假设结构体的首地址为0,第一个成员 num1 的首地址是 0 (满足规则2),它的类型是  int ,因此它占用地址空间 0&mdash;&mdash;3 。第二个成员 num3 是 double 类型,它占用 8 个字节,由于之前的 num1 只占用了 4  个字节,为了满足规则 2 ,需要使用规则 3 在 num1 后面填充 4 个字节(4&mdash;&mdash;7),使得 num3 的起始地址偏移量为 8 ,因此 num3  占用的地址空间是:8&mdash;&mdash;15。第三个成员 num2 是 int 型,其大小为 4 ,由于 num1 和num3 一共占用了 16  个字节,此时无须任何填充就能满足规则 2。因此 num2 占用的地址空间是 16&mdash;&mdash;19 。那么是不是结构体的总大小就是 0&mdash;&mdash;19 共 20  个字节呢?请注意,别忘了规则1!由于结构体内最大成员是 double 占用 8 个字节,因此最后还需要在 num2 后面填充 4 个字节,使得结构体总体大小为  24 。

struct S{ };  sizeof(S); // 结果为1

对于一个空 struct 结构体取 sizeof 运算,运算结果为 1 并非 0 。因为编译器为保证此空 struct 存在,专门分配一个字节。

如果存在结构体嵌套,无论内层还是外层均需要采用内存对齐。

6) 类的 sizeof

1.不含继承和 static 成员变量的类。

在这种情况下,只需要考虑对齐方式即可。

class A  {    public:    int b;    float c;    char d;  }; class B {  };  int main(void)  {    cout << “sizeof(A) is ” << sizeof(A) << endl;    //输出结果为12   cout << “sizeof(B) is ” << sizeof(B) << endl;    //输出结果为1   return 0 ;  }

2.类中存在静态成员变量

class A  {    public:    static int a;    int b;    float c;    char d;  };  int main()  {    A object;    cout << “sizeof(object) is ” << sizeof(object) << endl;    //输出结果为12   return 0 ;  }

因为在程序编译期间,就已经为 static 变量在静态存储区域分配了内存空间,并且这块内存在程序的整个运行期间都存在。而每次声明了类 A  的一个对象的时候,为该对象在堆上,根据对象的大小分配内存。

3.类中包含成员函数

class A  {    public:    static int a;    int b;    float c;    char d;    int add(int x,int y)    {      return x+y;    }  };  int main()  {    A object;    cout << “sizeof(object) is ” << sizeof(object) << endl;    b = object.add(3,4);    cout << “sizeof(object) is ” << sizeof(object) << endl;    //输出结果为12   return 0 ;  }

因为只有非静态类成员变量在新生成一个object的时候才需要自己的副本。所以每个非静态成员变量在生成新object需要内存,而function是不需要的。

3、sizeof 与 strlen 区别

int ss[20]="0123456789";  sizeof(ss)=80, //ss表示在内存中的大小,20*4。  strlen(ss)    //错误,strlen的参数只能是char*,且必须是以“\0”结尾的。  char *ss="0123456789";  sizeof(ss)=4,  //ss是指向字符串常量的字符指针。  sizeof(*ss)=1, // *ss是第一个字符。

到此,相信大家对“怎么使用C/C++基础sizeof”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

推荐阅读:
  1. memset与memcpy如何在C语言或C++中使用
  2. go语言相对于c/c++的优势有哪些

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

c++

上一篇:如何进行JavaMail开发

下一篇:Mysql数据分组排名实现的示例分析

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》