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

程序中,当我们建立了一个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. charles支持https抓包配置

    自从公司站点全部启用https后,使用charles就不能像以前那样愉快的抓包啦!不过没关系,这里教你怎么配置charles,使其支持https抓包.之前有一篇介绍charles的使用,参考这篇:ht ...

  2. mac下通过mdfind命令搜索文件

    mdfind命令就是Spotlight功能的终端界面,这意味着如果Spotlight被禁用,mdfind命令也将无法工作.mdfind命令非常迅速.高效.最基本的使用方法是: mdfind -name ...

  3. iOS UI特效

    1.iOS特效 a.对应APP中的基本动作分三类: 1.指向性动效(滑动,弹出等) 2.提示性动效(滑动删除,下拉刷新等) 3.空间扩展(翻动,放大等) b.这类动效在设计过程中需要主意几点: 1.系 ...

  4. Noip2016换教室(期望+DP)

    Description 题目链接:Luogu Solution 这题结合了DP和概率与期望,其实只要稍微知道什么是期望就可以了, 状态的构造很关键,\(F[i][j][0/1]\)表示已经到第\(i\ ...

  5. JAVA中的设计模式一(单例模式)

    单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建自己的唯一实例. 3.单例类必须给所有其他对象提供这一实例. 单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个 ...

  6. 《跟我学IDEA》五、快捷键(编码利器)

    上一篇博文,我们学习了idea的一些模版配置,但是只有模版是不行的,一款编辑器如何能为我们灵活的使用,快捷键的功劳不用多说大家也明白.今天我们就来学习快捷键的配置以及一些常用的快捷键的介绍,为让家能更 ...

  7. tp3.2 事务处理

    事务的机制通常被概括为“ACID”原则即原子性(A).稳定性(C).隔离性(I)和持久性(D).  原子性:构成事务的的所有操作必须是一个逻辑单元,要么全部执行,要么全部不执行.  稳定性:数据库在事 ...

  8. 使用 Kafka 和 ELK 搭建测试日志系统(1)

    本文仅供自己学习,不合适转载. 这是两篇文章的第一部分. 1. 安装 ELK 1.1 安装 ElasticSearch 在海航云上创建一个 Ubutu 16.4 虚机,2核4GB内存. (1)执行以下 ...

  9. Java NIO (四) 选择器(Selector)

    选择器(Selector) 是 SelectableChannle 对象的多路复用器,Selector 可以同时监控多个 SelectableChannel 的 IO 状况,也就是说,利用 Selec ...

  10. 正则验证,match()与test()函数的区别?

    test是RegExp的方法,参数是字符串,返回值是boolean类型.match是String的方法,参数是正则表达式,返回值是数组. 案例: //判断日期类型是否为YYYY-MM-DD格式的类型 ...