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

程序中,当我们建立了一个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语言中,把数组作为参数传递,接收数组的函数无法确定这个数组的长度。解决办法是,在传递数组的时候,把数组的长度作为单独的参数传递,或是把数组长度作为全局变量,这样传递的数组才是可用的。

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

  1. C++ 数组长度 以及 数组名作为参数传递给函数 以及 为什么不在子函数中求数组长度

    在看排序,首先是插入排序,思路理清后想用代码实现,然后问题来了: 如何求数组长度? 如果没记错,在Java中应该是有直接可用的方法的, Python中(序列)也有.len,在C/C++中,字符串倒是有 ...

  2. strlen()和sizeof()求数组长度

    在字符常量和字符串常量的博文里有提: 求字符串数组的长度 标准库函数strlen(s)可以返回字符串s的长度,在头文件<string.h>里. strlen(s)的判断长度的依据是(s[i ...

  3. c语言求数组长度

    在定义数组的函数内 int arr[] = {12.12}; int length; length = ]; 在别的函数中作为引用数据类型引入时,以上方法失效: 解决方法1:再传一个int 类型的长度 ...

  4. c++中求数组长度

    #include <iostream> using namespace std; template <class T> int getArrSize(T& arr){ ...

  5. 求任意长度数组的最大值(整数类型)。利用params参数实现任意长度的改变。

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

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

    转载声明:原文转自http://www.cnblogs.com/xiezie/p/5511707.html 昨天晚上,有个朋友找到我,他在用matlab编程,但是遇到一个问题,解决不了. 问题如下: ...

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

    问题: 求字符串中所含有字符的个数(包括空格),即求字符串长度: #include <stdio.h> #include <assert.h> int _strlen(cons ...

  8. 你必须知道的指针基础-4.sizeof计算数组长度与strcpy的安全性问题

    一.使用sizeof计算数组长度 1.1 sizeof的基本使用 如果在作用域内,变量以数组形式声明,则可以使用sizeof求数组大小,下面一段代码展示了如何使用sizeof: ,,,,,}; int ...

  9. 求数组中的最小子数组,时间复杂度o(n),java

    石家庄铁道大学 信1405-1 班 唐炳辉 题目:给定一个整数数组,找到一个具有最小和的子数组.返回其最小和. 设计思路:两个变量 ,一个记录当前并入的数组的值,另外一个记录所算过得最大的数组的值,当 ...

随机推荐

  1. 45、SQL逻辑查询语句执行顺序

    一 SELECT语句关键字的定义顺序 SELECT DISTINCT <select_list> FROM <left_table> <join_type> JOI ...

  2. JMeter脚本获取变量名、检验字符串值

    说明: 脚本中获取变量值用vars.get("变量名"); 校验String类型的值使用String.equals("字符串值"),而不能用String==&q ...

  3. JaveScript用二分法与普通遍历(冒泡)

    二分法 查找 概念: 从有序的数列中,折半查找. 思路: --> 找到数组中最中间的元素,将其作为基准 --> 从0开始判断数组中的元素,与基准进行比较 --> 比基准小的元素,存入 ...

  4. DeepLearning.ai学习笔记(四)卷积神经网络 -- week1 卷积神经网络基础知识介绍

    一.计算机视觉 如图示,之前课程中介绍的都是64* 64 3的图像,而一旦图像质量增加,例如变成1000 1000 * 3的时候那么此时的神经网络的计算量会巨大,显然这不现实.所以需要引入其他的方法来 ...

  5. Find all factorial numbers less than or equal to N

    A number N is called a factorial number if it is the factorial of a positive integer. For example, t ...

  6. 嵌入式设计初体验:永远的hello,world

    目前,xilinx的zynq系列FPGA炒的火热,SOC成为FPGA发展的必然趋势.可见所有功能均用硬件描述语言设计是不科学的.硬件逻辑独有的并行性使其在实时处理和并行算法中占尽优势,但当执行串行操作 ...

  7. Siamese Network理解

    提起siamese network一般都会引用这两篇文章: <Learning a similarity metric discriminatively, with application to ...

  8. Cleaner, more elegant, and wrong(msdn blog)

    Cleaner, more elegant, and wrong Just because you can't see the error path doesn't mean it doesn't e ...

  9. Cleaner, more elegant, and wrong(翻译)

    Cleaner,more elegant,and wrong 整洁,更优雅,但是错的 并不是因为你看不到错误的产生路径就意味着它不存在. 下面是C#编程书中的一个片段,摘自关于异常处理的章节. try ...

  10. Django2.0中文文档

    title: Django2.0中文文档 tags: Python,Django,入沐三分 grammar_cjkRuby: true --- Django2.0版本已经发布了,我们先来看一个图片 从 ...