【C深度剖析】sizeof操作符与数组
admin
2023-02-05 08:00:03
0

sizeof操作符与数组

一、  sizeof是何方神圣

说到sizeof,首先必须知道的一点:sizeof不是函数,sizeof是操作符。sizeof的作用就是,计算一个对象或类型所占的内存字节数。


  1.1 sizeof的语法

        sizeof()

这也正是为什么sizeof会有那么多人误解其为函数。括号里面可以是一个数据对象,也可以是一个数据类型。对于有括号的这种语法来说,你大可以不用理会括号里面是一个数据类型还是一个数据对象。

sizeof object:

初次见面,以为是语法错误,其实这也是sizeof的一种用法,计算数据对象所占的内存字节数。如果计算的是一个数据类型,那么请用上面的括号形式。如此看来,那么多程序员使用()的语法形式是有道理的,因为放之四海皆准。


1.2 sizeof如何计算大小

如果你学习过JAVA,那么你会发现,JAVA中根本不存在sizeof操作符。难道是因为JAVA不够完善吗?其实不然。JAVA之所以没有sizeof操作符,也正如JAVA设计者所言:JAVA不需要sizeofJAVA的运行时需要JVM的,不同的操作系统都有对应的JVM,在JVM中保证了所有类型的大小一致,不管你运行在32位还是64位的机器上,数据类型的大小都是已知的,这也正是JAVA可移植性能够实现的最根本的原因。回到话题来,为什么C/C++需要sizeof?显然,对于一个合格的C程序员,我们应该知道,我们所写的程序运行在不同结构的机器上的时候,类型的大小有所区别。当我们需要知道一个类型的大小才能继续写程序的时候,我们就需要sizeof。这就是为什么我们需要sizeof


、  数组并没有那么简单

  数组和指针是C语言中的重头戏,那么数组是什么数据类型呢?按照其他书籍的介绍,数组是复合类型(与基本数据类型结合构成的类型)。数组是同一类型的数据的集合,在内存中的表现为一串连续的内存,内存的大小为单个数据类型的大小与数据量的乘积。在我个人看来,数组更应该称为数据结构。数据结构中的顺序表,其实现的核心就是数组。由此可见,数组更像是一种C语言预先定义的数据结构。


  2.1 数组的语法



数据类型 数组名[数据个数]

倘若我们在定义的时候就初始化,那么数组中第一个维度的数据大小可以不写。


 2.2 数组名到底是什么

数组名是一段内存空间的名字,其指向了这段内存空间。我们讲到了sizeof,那么sizeof(数组名)计算出来的,理所应当计算的就是数组名指向的这段内存空间的字节数,事实也正是如此。但是,当我们对数组名继续深究下去,我们就会开始对sizeof(数组名)疑惑了。看下面的例子:

int arr[3] = {0,1,2};
printf(“%p”,arr);

上面的例子,打印的将会是数组首元素的地址。由此我们可以推测:arr是一个指针。我们这么推测是有理由的,因为指针才能存储一个地址。但是倘若我们想现在下定论,就需要考虑sizeof(arr)。这时候你再来回答,sizeof(arr)的大小是多少。两种答案:4或者12。答案是4的显示,我们把arr当做一个指针,指针的内存在所占的字节数为412则是把数组名看做一种数据结构,这个数据结构的大小为12字节。正确答案大家知道是12。到这里我们的疑惑就更深了,既然编译器认为arr不是指针,但是arr在打印地址的时候,又保存了一个地址。这就是我们需要说的:数组名是一个类似于指针的数据结构变量名。在普通情况下,我们可以把数组名当做指针来使用。继续看下面的一个例子:

int arr[3] = {0,1,2};
int arr2[3] = {3,4,5};
arr= arr2;

上面的代码我们想完成的事情是将arr2数组赋值给arr数组,但是编译的时候是错误的,因为arr在表现为指针属性的时候,实际上是一个常量指针。我们不会对一个已经初始化了的变量再次赋值。

 2.3 数组作为函数参数

  当数组作为函数形参的时候,数组名则沦为指针,既然是一个指针,我们就可以对其自增、自减和修改。在函数体内,数组名仅仅作为一个数组的指针。我们知道了他是指针,只要我们搞清楚这个指针实际指向的数据类型,那么对于指针的使用就显得简单了。



、  sizeof与数组

看下面的一段代码:

int arr[2][2] = {
{0,1},
{2,3}
};
printf(“%d,”,sizeof(arr));
printf(“%d,”,sizeof(arr[0]));
printf(“%d\n”,sizeof(arr[0][0]));

三个printf将会打印什么?答案:16,8,4


 3.1 sizeof(arr)


弄清楚答案的缘由我们先了解一下多维数组。

C/C++中,多维数组实际上是一位数组。多维数组在分配内存的时候,是分配一段完整的连续的内存空间。这么说可能理解不深刻。我们先来了解一下JAVA中的多维数组,就以二维数组来看。JAVA中的二维数组在分配空间的时候,首先会分配一个大小为2的数组,其保存的是2个一维数组的起始地址。这两个一维数组在内存上并不一定是连续的。再看看C中的数组,就能理解其完整的连续的意思。

正是因为如此,所以sizeof(arr)才会打印16。因为sizeof计算的是数组名对应的内存空间的大小,不管维度大小。


 3.2 sizeof(arr[0])


   接下来我们看一下sizeof(arr[0])。如果外面没有sizeof操作符,arr[0]在此处如果换成指针来看待,其运算如下:(arr + 0 ),其指向的依然是数组的首行首元素的地址。但是在sizeof操作符下,arr[0]显然不能够当做指针来看待,这时应该理解为二维数组的一维数组(逻辑上是如此,实际上多维数组还是一位数组)。arr[0]指向的是第一行的一位数组,我们可以理解为arr[0]就是一个数组名,其内存空间为arr数组的前2个元素对应的内存空间,我们sizeof,得到的结果就应该为8


 3.2 sizeof(arr[0][0])


最后来看sizeof(arr[0][0])arr[0][0]表示访问的是二维数组的首行一维数组的首元素,其变量就是一个int类型,所以结果为4

由此看来,数组名与sizeof操作符搭配的时候,其表现也并不简单,其依然还是保留了数组名作为一种数据结构的特性。



相关内容

热门资讯

德国总理:美国正在被伊朗羞辱 德国之声4月27日报道,德国总理默茨在访问一所学校时表示,在当前的持续冲突中,伊朗领导层正试图羞辱美...
理响中国|“长”歌以行,风云激... 光阴如梭,东方潮阔。这里是中国的长三角,世界的长三角。无论过去、现在还是未来,这片土地都因时代而生,...
白宫:特朗普及其国安团队开会讨... 新华社华盛顿4月27日电 美国白宫新闻秘书莱维特27日在记者会上证实,总统特朗普及其国家安全团队当天...
人民日报刊文:日本放开杀伤性武... 日本放开杀伤性武器出口推高地缘冲突风险(国际论坛)常思纯《人民日报》(2026年04月28日 第 0...
医疗保障法草案二审:明确生育保... 满足多样化健康保障需求本报记者 彭 波4月27日,医疗保障法草案二审稿提请十四届全国人大常委会第二十...
天津一景区发生自转旋翼机事故1... 澎湃新闻记者 吕新文中国民用航空华北地区管理局4月22日公布《豪客通航“10•1”天津长芦汉盐旅游区...
卡塔尔埃米尔与美国总统特朗普通... 当地时间24日,卡塔尔埃米尔塔米姆与美国总统特朗普通电话,重点就中东地区局势以及伊朗与美国谈判问题交...
男子30年前被扣押2859克黄... 澎湃新闻记者 王鑫家住辽宁省大连市的潘永嘉近日向澎湃新闻反映称,三十年前,他在大连周水子机场被盖州市...
商务部:取消反制欧盟两家金融机... 中华人民共和国商务部令二〇二六年 第1号鉴于欧盟已取消对中国两家金融机构的制裁措施,现公布《关于取消...
过去24小时共有5艘船只通过霍... 总台记者当地时间24日获悉,过去24小时内,共有5艘船只通过霍尔木兹海峡,其中包括一艘伊朗油轮。(总...