求教:C语言中如何求任意一个int型数组的长度?

lbiori241 2006-02-05 06:27:41
即:int length(int ar[]);只给出数组首地址,返回该数组的长度
C语言中对数组的操作不太灵活,而数组操作又是不可或缺的,求大虾解惑
...全文
35542 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
JustNewBie 2006-02-14
  • 打赏
  • 举报
回复
!!!!!
确实是错了,8好意思,郁闷....!!!!
yuzl32 2006-02-10
  • 打赏
  • 举报
回复
int length(int ar[]);退化为指针.求不了!
prostar 2006-02-09
  • 打赏
  • 举报
回复
比如:

int p[100] ;
那么
int size = sizeof( p ) / sizeof( p[0] ) ;
就ok了
ox_thedarkness 2006-02-09
  • 打赏
  • 举报
回复
不可能有办法的。
当你定义一个数组的时候:
int a[] = {1, 2, 3}; // 实际上被编译为 int a[3] = {1,2,3}

数组名代表的是数组的地址。注意 —— 你绝对没有办法通过数组名动态获得数组的大小。当你丢失a的长度信息的时候,你永远不可能知道他的长度。

那么 sizeof 是怎么回事呢?他不是通过 a 的名字获得 a的大小了么? —— 大错特错!

关键字 sizeof 产生的是一个编译期常量(注1) 他的运作方式是这样的:

当你写:
sizeof a
实质是:
sizeof ( a的类型 )

而a的类型是什么呢?编译器察看 a的定义发现, 是 int [3]
就是说,这里 sizeof a 实质是:
sizeof ( int[3] )
完全等同于常量 12 (假定int为4字节)。


考虑一个函数
void func( int a[] );
// 写成 int a[3] 也不会有本质区别——也许你该试试写成 int (&a) [3] ?

C++规定,数组作为形参的时候,a代表数组首地址。
他的底层意义是: a 退化为了一个4字节的指针,没有任何变量表示数组的大小会“自动”被传递进来。

我们看看这个时候 sizeof a是什么:
sizeof( 函数形参的a[] ) = sizeof( int* const ) = 4 // 当然a[]不是合法的C++类型



仍然不服气?好——我们反问一个问题:若你是C /C++的设计者, 你怎么在兼容原有设计的基础上让void func( int a[] )同时传递地址和大小?

首先,a是一个变量,而且类似数组。他必须是一个地址,否则你不知道如何索引元素。
他怎么再带上一个变量表示他的大小呢?

扩充 sizeof (a) 的能力?

sizeof a 必须产生代码——不管是常量还是什么。 要让他在运行时决定 a的值, a就必须带上他的大小信息。

1 你必须修改C标准,让C支持“两种”数组。一种是定义处的数组,他分配大片连续内存,和原来的C标准相同。

2 另一种是作为参数传递数组。 你必须传递地址和数组大小;这个数组实际上是一个8字节的结构{ 地址; 大小}(事实上可能更加复杂,考虑多纬数组如何实现? )

3 系统必须根据两种不同数组分别实现其 []、* 、&等。 原有的数组根据其首地址偏移(这是个常量)和下标寻址; 而参数数组则首先取“地址”内容(这是个变量),然后根据这个地址寻址....

厄... 再考虑多维数组——听起来这不是一整套vector模型么?

-----------------------------------------------
注1: 对于C99支持的 flexible array ,其 sizeof 运算是运行时求值
lbiori241 2006-02-09
  • 打赏
  • 举报
回复
我是楼主,我补充说明一下我原来的命题,楼上很多人都没有理解我的意思,我看了楼上一些说能求出长度的朋友们给出的程序,都是实际上先定义了一个已知长度的数组,比如 ox_thedarkness() 兄给出的:char str[] = "Some thing for test";//长度为20
int a[] = { 1, 3, 4 };//长度为3
int b[20];//长度为20
既然长度已知,再写个求长度的函数是没有意义的。

我的意思是:一个不知道长度的但是已经存在了的数组。比如,一个数组ar[]是在主函数中定义的,但是在另外一个函数fun(ar[])中,参数为数组的首地址,并没有传入数组长度,请注意在fun函数中数组是传进来的,并不是在fun中定义的。而此时在fun(ar[])函数中又必须知道数组的长度才能进行循环操作,那么此时在fun函数中,仅凭数组首地址这一个参数如何求得数组的长度?
lbiori241 2006-02-09
  • 打赏
  • 举报
回复
回JustNewBie(懒惰+骄傲+不耐心!) ,sizeof(ar[])是不行的,编译都通不过
ox_thedarkness 2006-02-09
  • 打赏
  • 举报
回复
1 C风格数组在定义时可以通过sizeof计算出大小,如:

#define AR_SIZE( a ) sizeof( a ) / sizeof( a[0] )

char str[] = "Some thing for test";
int a[] = { 1, 3, 4 };
int b[20];

AR_SIZE( str ); //20
AR_SIZE( a ); //3
AR_SIZE( b ); //20

注意,sizeof是编译器间静态求值的。他必须知道对象的准确类型。


2 数组作为函数参数,作用类似指针。 函数只传递一个4字节的地址,而没有其大小信息。

楼上 JustNewBie(懒惰+骄傲+不耐心!) 做法是错误的。

int length(int ar[])
{
sizeof ar; // 永远是4(当然,在16位编译器下是2 )
}

3 C99支持动态数组,你可以查查资料,似乎有支持自动指定大小——但是目前支持C99的编译器很少,我没有试过。

JustNewBie 2006-02-09
  • 打赏
  • 举报
回复
我查了一下其他的资料,好像C语言的确不能解决
楼上的,我的命题说的是仅知道数组的首地址,你一开始就申明了一个P[100],一看都知道长度为一百,还要函数求作什么呢?

/**********************************************/

楼主我上面不是给你写了吗?
c语言中数组元素个数是编译时求值的,要求定义时就给出个数或者直接初始化由编译器安排
足够的大小.

int length(int ar[])
{
return sizeof(ar[])/sizeof(ar[0]);
}
就可以了啊,不管你数组是什么类型的.
minus273 2006-02-09
  • 打赏
  • 举报
回复
牛角尖一族
传长度是正解
lbiori241 2006-02-09
  • 打赏
  • 举报
回复
我查了一下其他的资料,好像C语言的确不能解决
楼上的,我的命题说的是仅知道数组的首地址,你一开始就申明了一个P[100],一看都知道长度为一百,还要函数求作什么呢?
zez 2006-02-06
  • 打赏
  • 举报
回复
int length(int ar[])
如果ar是用malloc 分配的,并且在windows下,可以用 _msize(ar)/sizeof(int)

其它情况,没有办法!!!
JustNewBie 2006-02-06
  • 打赏
  • 举报
回复
elem_num = sizeof(array[])/sizeof(array[0]);
huanmm 2006-02-06
  • 打赏
  • 举报
回复
至于楼主的问题,C语言是无法解决的。只能把数组的长度作为参数传递。

当然也可以这样:
#include "stdio.h"

typedef struct array_box
{
int array[10];
}ARRAY_BOX;

void getData(ARRAY_BOX * arrayBox_p)
{
int count = sizeof(arrayBox_p->array) / sizeof(int);
int i;
for (i = 0; i < count; i++)
{
arrayBox_p->array[i] = i;
}
}

main()
{
ARRAY_BOX arrayBox;
getData(&arrayBox);
}

做一个只有一个类型为数组的元素的结构体,相当于把数组用一个box包起来,占用的内存空间相同,但是可以达到楼主想要得效果。

至于想要知道数组实际使用长度,那真是没有任何办法了,只有自己数吧~~
huanmm 2006-02-06
  • 打赏
  • 举报
回复
> 如果作为函数的参数是没法求的,
> 但这样是可以的:
>
> #define LENGTH(s) (sizeof(s) / sizeof(int))
>
> int s[12];
> int length = LENGTH(s);
==================================================
这样的方法只能用于数组变量的数组名,对于指向数组的指针,以及作为参数的数组名都是没有效果的,上面已经有人解释了


> 楼上流星骑士的程序我在win-tc上调试有问题,出错在p=a;错误说明是“说明需要类型或存储> 器种类”,这是什么意思啊
==================================================
p的类型是WORD*,a的是WORD数组的数组名,在有的编译器上可以忽略,在有的编译器上则认为他们是不同类型,可以改为“p = &a[0]”,这样在任何编译器上都是正确的


> #include "STDIO.H"
>
> typedef int WORD;
> WORD a[10];
> WORD *p=NULL;
> WORD count=0;
> p=a;
> WORD main(void )
> {
> while(!p==NULL)
> {
> p++;
> ++count;
> }
> return count;
> }
==================================================
p指针不停的++,怎么可能等于NULL,加到最后就跑到系统禁区了,这样不是死循环就是Window Error。
lbiori241 2006-02-06
  • 打赏
  • 举报
回复
楼上流星骑士的程序我在win-tc上调试有问题,出错在p=a;错误说明是“说明需要类型或存储器种类”,这是什么意思啊
三文鱼也会飞 2006-02-06
  • 打赏
  • 举报
回复
#include "STDIO.H"

typedef int WORD;
WORD a[10];
WORD *p=NULL;
WORD count=0;
p=a;
WORD main(void )
{
while(!p==NULL)
{
p++;
++count;
}
return count;
}
loujing 2006-02-06
  • 打赏
  • 举报
回复
如果在C++中就好了,不用数组,用vector,有内建的length方法。
iamcaicainiao 2006-02-05
  • 打赏
  • 举报
回复
int length(int ar[]);只给出数组首地址,返回该数组的长度

这种,似乎是没有办法求长度的。
iamcaicainiao 2006-02-05
  • 打赏
  • 举报
回复
计算内存容量
用运算符sizeof可以计算出数组的容量(字节数)。示例7-3-3(a)中,sizeof(a)的值是12(注意别忘了’\0’)。指针p指向a,但是sizeof(p)的值却是4。这是因为sizeof(p)得到的是一个指针变量的字节数,相当于sizeof(char*),而不是p所指的内存容量。C++/C语言没有办法知道指针所指的内存容量,除非在申请内存时记住它。

注意当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。示例7-3-3(b)中,不论数组a的容量是多少,sizeof(a)始终等于sizeof(char *)。

char a[] = "hello world";
char *p = a;
cout<< sizeof(a) << endl; // 12字节
cout<< sizeof(p) << endl; // 4字节
示例7-3-3(a) 计算数组和指针的内存容量

void Func(char a[100])
{
cout<< sizeof(a) << endl; // 4字节而不是100字节
}
示例7-3-3(b) 数组退化为指针
搬不搬砖 2006-02-05
  • 打赏
  • 举报
回复
sizeof(s) / sizeof(int)就是数组s的元素个数呀, 动态的可以用指针呀
加载更多回复(4)

69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧