`

如何求c语言中数组长度(sizeof)-->编译原理很重要

 
阅读更多
#include "stdio.h"

void getlen(char a[]);
main()
{
  char a[]="12345";
  printf("%d\n",sizeof(a));//这里可以通过数组名求出数组长度 
  getlen(a);
  
  getchar();  
}

void getlen(char a[])  //当数组名退化成指针以后是求不出数组长度了
{
  printf("%d\n",sizeof(a));     
}

执行结果:



如果作为函数的参数是没法求的,
> 但这样是可以的:
>
> #define LENGTH(s) (sizeof(s) / sizeof(int))
>
> int s[12];
> int length = LENGTH(s);
==================================================
这样的方法只能用于数组变量的数组名,对于指向数组的指针,以及作为参数的数组名都是没有效果的,上面已经有人解释了
》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
不可能有办法的。
当你定义一个数组的时候:
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 运算是运行时求值

分享到:
评论

相关推荐

    C语言介绍sizeof的使用方法,可以直接编译使用

    程序通过简洁的代码展示了如何使用sizeof来查找各种变量类型的大小,这是C语言编程中重要的一环,非常适合初学者进行学习。 程序的主要目标是确定各种类型的变量在内存中的大小。 程序的开头,我们包含了stdio.h...

    计算机编程C语言-预处理

    数组的使用包括取值、赋值、计算数组长度等。例如:`int nums[5] = {1,2,3,4,5}; nums[0] = 10;`。数组的长度可以使用`sizeof`运算符计算,例如:`int length = sizeof(nums) / sizeof(nums[0]);`。 二、预处理命令...

    C语言中各种数据类型长度.pdf

    AnsiC规定sizeof(char) 必须返回 1,当sizeof作用于数组时,返回的是数组中所有成员所占的字节数(注意并不是数组中成员的个数),当sizeof()作用于结构体和公用体时,返回的不仅仅是数据成员总的字节数,还包括...

    C语言大学教程--c语言复习课件.ppt

    C语言大学教程--c语言复习课件.ppt 本知识点总结了C语言的基本知识点,包括C程序的基本结构、main函数、C程序的执行步骤、C程序的结构、数据类型、基本运算和表达式等。 一、C语言的基本知识(执行步骤) * C语言...

    c++ 面试题 总结

    内存管理是操作系统中的重要部分,两三句话恐怕谁也说不清楚吧~~ 我先说个大概,希望能够抛砖引玉吧 当程序运行时需要从内存中读出这段程序的代码。代码的位置必须在物理内存中才能被运行,由于现在的操作系统中...

    C语言中关于sizeof 和 strlen的区别分析

    1、编译时计算运算符sizeof,可用类型或变量做参数,计算占用内存的大小。sizeof后若是类型必须加括弧,若是变量名可不加括弧。sizeof(x)可用来定义数组维数如: 代码如下: printf(“%d\n”, sizeof(short));  ...

    9.第九章 数组.txt

    数组总字节数=sizeof(类型说明符)*数组长度=sizeof(数组名)。 9.2.2 一维数组引用 数组元素的的标识方法为数组名后跟下标。引用数组元素的一般形式为:数组名[下标]。下标只能为整型常量、整型变量、整型表达式。 ...

    明解C语言(第3版)入门篇.[日]柴田望洋(带详细书签).pdf 【半高清】

    结构体成员和->运算符 346 结构体和typedef 348 结构体和程序 350 聚合类型 351 返回结构体的函数 351 命名空间 353 结构体数组 353 派生类型 355 12-2 作为成员的结构体 356 表示坐标的结构体 356 具有...

    C语言入门经典(第4版)--源代码及课后练习答案

    书中除了讲解C程序设计语言,还广泛介绍了作为一名C程序设计人员应该掌握的必要知识,并提供了大量的实用性很强的编程实例。本书的目标是使你在C语言程序设计方面由一位初学者成为一位称职的程序员。读者基本不需要...

    C语言程序设计标准教程

    当对全部元素作初始化赋值时,也可不给出数组长度。 [例7.4]计算学生的平均成绩和不及格的人数。 struct stu { int num; char *name; char sex; float score; }boy[5]={ {101,"Li ping",'M',45}, {102,"Zhang ping",...

    C语言讲义.doc

    1.10 C语言编译过程,GCC参数简介 16 1.10.1 C语言编译过程 16 1.10.2 -E预编译 16 1.10.3 -S汇编 16 1.10.4 -c编译 16 1.10.5 链接 16 1.11 操作系统结构 17 1.11.1 用户模式 17 1.11.2 内核模式 17 1.12 64位,32位...

    《你必须知道的495个C语言问题》

    1.24 我在一个文件中定义了一个extern数组,然后在另一个文件中使用,为什么sizeof取不到数组的大小? 13 声明问题 14 1.25 函数只定义了一次,调用了一次,但编译器提示非法重声明了。 14 *1.26 main的正确...

    C语言中sizeof()与strlen()的区别详解

    sizeof()和strlen()经常会被初学者混淆,但其中有有很大区别: sizeof() 1. sizeof()【操作数所占空间的字节数大小】是一种c中的基本运算符。 可以以类型、指针、数组和函数等作为参数。 头文件类型为unsigned int。...

    你必须知道的495个C语言问题

    1.24 我在一个文件中定义了一个extern数组,然后在另一个文件中使用,为什么sizeof取不到数组的大小? 声明问题 1.25 函数只定义了一次,调用了一次,但编译器提示非法重声明了。 *1.26 main的正确定义是什么...

    c语言基础练习题及答案.pdf

    解释:strlen函数返回字符串的长度,sizeof运算符返回数组的大小,strlen(st)返回0,因为字符串st为空,sizeof(st)返回20,因为数组st的大小为20字节。 20. 以下程序的输出结果是 6。 解释:for循环从1到100,b的...

    高级语言程序设计00342学习资料1.pdf

    理由是,C语言中strlen函数返回字符串的长度,sizeof运算符返回数组的总字节数。 8. 变量定义并初始化正确的是 C、int a=3,p=&a;。理由是,C语言中变量定义并初始化需要使用赋值语句,且指针变量需要使用地址...

Global site tag (gtag.js) - Google Analytics