在把数组作为参数传递给函数时,可以通过sizeof运算符告诉函数数组的大小吗?

在把数组作为参数传递给函数时,可以通过sizeof运算符告诉函数数组的大小吗?,第1张

不可以。当把数组作为函数的参数时,你无法在程序运行时通过数组参数本身告诉函数该数组的大小,因为函数的数组参数相当于指向该数组第一个元素的指针。这意味着把数组传递给函数的效率非常高,也意味着程序员必须通过某种机制告诉函数数组参数的大小。

为了告诉函数数组参数的大小,人们通常采用以下两种方法:

第一种方法是将数组和表示数组大小的值一起传递给函数,例如memcpy()函数就是这样做的:

char source[MAX],dest[MAX];

/... /

memcpy(dest,source,MAX);

第二种方法是引入某种规则来结束一个数组,例如在C语言中字符串总是以ASCII字符NUL('\0')结束,而一个指针数组总是以空指针结束。请看下述函数,它的参数是一个以空指针结束的字符指针数组,这个空指针告诉该函数什么时候停止工作:

void printMany(char strings口)

{

int i;

i=0;

while(strings[i]!=NULL)

{

puts(strings[i]);

++i;

}

}

正象9.5中所说的那样,C程序员经常用指针来代替数组下标,因此大多数C程序员通常会将上述函数编写得更隐蔽一些:

void printMany(char strings[])

{

while(strings)

{

puts(strings++);

}

}

尽管你不能改变一个数组名的值,但是strings是一个数组参数,相当于一个指针,因此可以对它进行自增运算,并且可以在调用puts()函数时对strings进行自增运算。在上例中,while(strings)

就相当于

while(strings !=NULL)

在写函数文档(例如在函数前面加上注释,或者写一份备忘录,或者写一份设计文档)时,写进函数是如何知道数组参数的大小是非常重要的,例如,你可以非常简略地写上“以空指针结束”或“数组elephants中有numElephants个元素”(如果你在程序中用数字13表示数组的大小,你可以写进“数组arr中有13个元素”这样的描述,然而用确切的数字表示数组的大小不是一种好的编程习惯)。

通过sizeof可以计算出类型的长度,同样也可以计算出数组的长度,但是这具有一定的局限性。

以下是一段示例代码:

session 1: 计算出数组的长度

session 2: 通过函数计算出数组的长度

session 3: 通过函数计算出数组的长度

运行结果:

通过sizeof可以计算出类型的长度,同样也可以计算出数组的长度,但是这具有一定的局限性。

以下是一段示例代码:

session 1: 计算出数组的长度

session 2: 通过函数计算出数组的长度

session 3: 通过函数计算出数组的长度

1L正确,2L错误。

测试代码:

#include <stdioh>

int main()

{

char str[] = "world", pstr = "world";

printf("%d %d",sizeof(str),sizeof(pstr));

getchar();

return 0;

}

Dev-C++下编译通过,运行结果6 4。

----

解释:

char str[] = "world";

这里初始化不限定长度,而"world"包含结束符'\0'后为6个字符,因此初始化str的长度是6;又因为char数组中每个元素(char变量)占用1个字节的空间,所以str[]数组的大小是6字节。

char pstr = "world";

由于pstr是指针,无论是否指向字符串,指向什么字符串,sizeof(pstr)等于sizeof(int),32位平台上等于4。

造成差别的原因:

这里char str[] = "world";声明并定义了一个数组str[](当然,C语言的语法不允许在定义之外这样引用整个数组,以下这样的写法只是为了区分语义),之后标识符str有双重语义:一是如2L所说的类型为char const的地址常量,它的值等于数组中首个元素的地址,即str等价于(char const)&str[0];二是表示整个str[]数组这个语法对象。在sizeof(str)中,str表示的含义是str[],因此返回整个数组的大小(这个大小在之前的数组定义中已经确定了);而pstr只是个指针,sizeof(pstr)只能返回指针本身占用的字节数而不能确定为它指向的内容分配的空间的大小。

(注意,地址常量绝不是指针,类型不同!虽然在函数的参数传递过程中,地址常量可以退化成对应的指针。这里LZ和2L显然由于这个错误理解导致对数组的sizeof()结果判断有误。)

关于数组名语义规定以及2L错误的剩余部分(“数组名实际上就表示一个指针”)的原因见http://zhidaobaiducom/question/133592005正文最后两段。

====

[原创回答团]

当数组名作为函数参数传递后,“退化”为指针,sizeof自然也就不能得到数组的长度,只是得到一个指针的长度而已。

你的试验代码里,数组名并没有作为函数参数传递过,他还是一个数组名,所以sizeof还是能得到数组的长度。

参数char str[] 等同于 char str;而str表示指向头元素的指针,而C/C++语言中把指针是看成一个是对地址的编码。在32位的系统中,这个编码是用一个32位的整数来表示的,也就是说如果你用sizeof(str)计算这个数组的长度就相当于sizeof(int)一个,其结果是4。如果你的目的是要表示这个数组的长度就得使用strlen(str)/sizeof(str[0]);strlen(str)表示的是str真是表量的长度。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/langs/13493999.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2025-09-01
下一篇2025-09-01

发表评论

登录后才能评论

评论列表(0条)

    保存