【C深度剖析】sizeof操作符与数组-创新互联

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不需要sizeof。JAVA的运行时需要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当做一个指针,指针的内存在所占的字节数为4;12则是把数组名看做一种数据结构,这个数据结构的大小为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操作符搭配的时候,其表现也并不简单,其依然还是保留了数组名作为一种数据结构的特性。

另外有需要云服务器可以了解下创新互联cdcxhl.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


文章标题:【C深度剖析】sizeof操作符与数组-创新互联
网站链接:http://ybzwz.com/article/dhsohh.html