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;
}



运行结果为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;   //不合理

对类型使用 sizeof 时,sizeof type_name 是非法的,必须写为 sizeof(type_name);


无论是对对象还是类型取值,sizeof () 这种形式都是对的;


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

unsigned 不影响内置类型 sizeof 的取值


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

指针变量的 sizeof 值与指针所指的对象类型没有任何关系,与指针申请多少空间没有关系,所有的指针变量所占内存大小均相等。


如果使用 32 位编译器编译得到程序是 32 位,那么在 64bits 系统下,指针变量大小仍然是 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 。


数组的大小是各维数的乘积*数组元素的大小。


向函数形参传递数组,数组将会退化为指针,失去原来数组的特性。




 


相关文章
|
6月前
|
C++
C/C++】如何不使用 sizeof 求数据类型占用的字节数
C/C++】如何不使用 sizeof 求数据类型占用的字节数
|
6月前
|
C语言 C++
C++ sizeof()运算符的参数为指针和数组的值为什么不同
C++或C语言中,都可以使用sizeof()运算符来计算数组的字节大小,除此之外,在C++和C语言中,都可以使用一个指向数组第一个元素的内存地址的指针来引用数组,因此,如果要计算数组的字节大小,或长度,传递数组本身或传递指向数组的指针给sizeof()运算符似乎都是可以的,实际上则不然,
72 5
|
6月前
|
Linux C++
(C++)VS下sizeof(string(““))与linux-g++下sizeof(string(““))大小区别及原因剖析
(C++)VS下sizeof(string(““))与linux-g++下sizeof(string(““))大小区别及原因剖析
63 0
(C++)VS下sizeof(string(““))与linux-g++下sizeof(string(““))大小区别及原因剖析
|
6月前
|
安全
来自c++primer5的sizeof运算符
来自c++primer5的sizeof运算符
36 0
|
存储 编译器 C++
C++ sizeof 的介绍
C++ sizeof 的介绍
113 0
|
C++
如何在不使用 sizeof 的情况下在 C/C++ 中找到数组的大小?
我们可以使用 sizeof 运算符找到数组的大小
153 0
|
Linux C++
嵌入式linux基础:c++(五)构造函数
嵌入式linux基础:c++(五)构造函数
160 0
嵌入式linux基础:c++(五)构造函数
|
Linux 编译器 C++
嵌入式linux基础:c++(四)重载 指针 引用
嵌入式linux基础:c++(四)重载 指针 引用
144 0
嵌入式linux基础:c++(四)重载 指针 引用
|
Linux C++
嵌入式linux基础:c++(三)程序结构
嵌入式linux基础:c++(三)程序结构
162 0
嵌入式linux基础:c++(三)程序结构
|
编译器 C语言 C++
C/C++ 中的 sizeof 运算符和 size_t 类型
C/C++ 中的 sizeof 运算符和 size_t 类型