C陷阱:求数组长度

// 这是一篇导入进来的旧博客,可能有时效性问题。

程序中,当我们建立了一个int型数组:
int a[]={1,2,3,4,5,6};
随后我们可能需要知道它的长度,此时可以用这种方法:
length = sizeof(a)/sizeof(a[0]);

这种方法很实用,但是能不能用一个自定义函数接收一个数组作为参数,求其长度呢?
直觉上,我们可能会写出这样的程序:

#include<stdio.h>

int len(int a[])

{

int len = sizeof(a)/sizeof(a[0]);

return len;

}

int main()

{

int a[]={11,12,13,14,15,16};

printf("%d\n", len(a));

return 0;

}
但是很快我们就会发现结果是错误的。仔细分析会发现,在len(int a[])函数中,sizeof(a)的结果实际上是a指针的长度(在我的系统中长度是8),而不是整个数组a的长度。
这是由于,当把数组作为参数传递时,数组退化为了指针,因此不再能得到数组长度

我在网上看到了有人说用一种指针的方法可以做到在函数中求数组参数的长度,我把他的代码稍作修改便于观察调试,如下:

#include<stdio.h>

int len(int a[])

{

int len = 0;

int *p;

p = a;

while((*p)!=NULL)

{

printf("current pointer: %d\n", p);

printf("current value: %d\n", *p);

p++;

len++;

}

printf("current pointer: %d\n", p);

printf("current value: %d\n\n", *p);

return len;

}

int main()

{

int a[]={11,12,13,14,15,16};

printf("actual length: %d\n\n", sizeof(a)/sizeof(a[0]));

printf("length: %d\n",len(a));

return 0;

}
在我的系统中,某次运行结果是这样的:

分析程序和结果,首先我们知道这种方法是错误的(结果有时是正确的有时是错误的,图中是错误的结果)。
其次,我们看到,当对指针p进行自加一操作,p确实会诚实地指向下一元素的地址(本例中是地址自加4,即int长度)。
最后,程序中用(*p)!=NULL作为判断条件,判断是否已经超过数组范围,这一操作是危险的,因为它产生了数组越界,而这在C语言中得不到警告。程序越界访问了不可预测的地址内容,在10485320处得到了一个不可预测的值1,并把它也算作数组中的一个元素。在下一个地址也就是10485324处,值为0,看作了NULL,数组结束。

结论: C语言中,把数组作为参数传递,接收数组的函数无法确定这个数组的长度。解决办法是,在传递数组的时候,把数组的长度作为单独的参数传递,或是把数组长度作为全局变量,这样传递的数组才是可用的。

原文地址:https://www.cnblogs.com/yangleda/p/8320785.html

时间: 2024-11-24 12:23:26

C陷阱:求数组长度的相关文章

求数组长度sizeof

当数组当作参数传递时,它就退化成指针了,要求数组长度的话,可以在main函数内部求得 #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> void fun(int arr[], int len) {     printf("---%d\n", sizeof(arr));     printf("---%d\n", sizeof(arr[0]));    printf("---len = %d

c语言求数组长度

在定义数组的函数内 int arr[] = {12.12}; int length; length = sizeof(arr)/arr[0]; 在别的函数中作为引用数据类型引入时,以上方法失效: 解决方法1:再传一个int 类型的长度参数进来 解决方法2:在末端定义一个不可能的数据,如-1作为标志位

C++ 数组长度 以及 数组名作为参数 传递给函数

在看排序,首先是插入排序,思路理清后想用代码实现,然后问题来了: 如何求数组长度? 如果没记错,在Java中应该是有直接可用的方法的, Python中(序列)也有.len,在C/C++中,字符串倒是有strlen() (需要#include <string.h>) 一个办法是用 sizeof() 一.首先定义数组 int array[] = {18,10,15,7,1}; 一开始想都没想就直接在子函数里面 int array_length(int a[]){ int len = sizeof(

求字符串长度 strlen(数组指针两种方式)

问题: 求字符串中所含有字符的个数(包括空格),即求字符串长度: #include <stdio.h> #include <assert.h> int _strlen(const char* str) { assert(str != NULL); int i=0; for(;*str++!='\0';i++); //for(;str++!=NULL;i++);//有些说这句也可以,但执行结果是死循环,str++即使越界也未必为NULL; return i; } int _strle

求数组中最长递增子序列的长度

个人信息:就读于燕大本科软件工程专业 目前大三; 本人博客:google搜索"cqs_2012"即可; 个人爱好:酷爱数据结构和算法,希望将来从事算法工作为人民作出自己的贡献; 编程语言:C++ ; 编程坏境:Windows 7 专业版 x64; 编程工具:vs2008; 制图工具:office 2010 powerpoint; 硬件信息:7G-3 笔记本; 真言 怒冲北京,为理想前行. 题目 解法 使用工具栈单枝遍历数组(思路源于工具栈可以双枝遍历二叉树的方法) 栈里存放的是数组的下

输入n个数组,数组长度不等,每个数组取出一个数进行组合,求出所有的组合。

转载声明:原文转自http://www.cnblogs.com/xiezie/p/5511707.html 昨天晚上,有个朋友找到我,他在用matlab编程,但是遇到一个问题,解决不了. 问题如下: 输入n个数组,数组长度不等,从每个数组取出一个数进行组合,求出所有的组合. 例子: int a[]={1,2}; int b[]={3,4,5}; 可能的组合:{1,3}:{1,4}:{1,5}:{2,3}:{2,4}:{2,5}: 搞了40分钟左右,不辱使命~ JAVA代码实现: import j

[算法]求数组中最长递增子序列长度

思路: 1.开辟数组L,L[i]记录的为a[0]~a[i]的最长递增子序列长度 2.开辟数组maxV,maxV[i]记录的为长度为i的各递增子序列的最后一个元素的最小值,譬如有子序列 1,2,4 1,2,5 则maxV[3] = 4 3.使用maxLen记录当前的最长递增子序列长度 4.转移方程: L[i+1] = max{1,L[j]+1] , a[i] > maxV[j] && j <= maxLen int LIS(int* a, int n){ int* maxV =

0130 遍历数组:数组遍历、数组长度、注意点、求数组中的最大值等案例

1.4.1 数组遍历 ? 遍历:把数组中的每个元素从头到尾都访问一次(类似学生的点名),可以通过 for 循环索引遍历数组中的每一项. var arr = ['red','green', 'blue']; for(var i = 0; i < arr.length; i++){ console.log(arrStus[i]); } 1.4.2 数组的长度 数组的长度:默认情况下表示数组中元素的个数 使用"数组名.length"可以访问数组元素的数量(数组长度). var arrS

数组-----求字符串长度

//求字符串长度 #include"stdafx.h" #include<iostream> using namespace std; void main(){ char s[201]; int i = 0; cout << "Please enter a string(ended with enter):" << endl; cin.getline(s, 200); //cin.getline()的使用 while (s[i])