C语言数组元素下标为何从0开始

很多同学可能在学习数组时会有这个疑问,下标为什么不从1开始呢?从1开始不是更符合大家的日常习惯吗?生活中我们通常说第1个,而不是第0个。的确,有些计算机语言如早期的Pascal语言,数组元素的下标是从1开始的。难道是C语言故意要与众不同?要弄清楚这个问题,得先看一下计算机底层是怎样处理数组元素的。我们先编写了一个小程序,然后在visual
studio中对其进行了反汇编。源程序和反汇编后的部分代码如下:

源程序:

int arr[5];  //一个全局数组

int main()

{

int i;

for (i =0;i < 5;i++)

arr[i] = 9;

return 0;

}

反汇编后的部分代码:


int i;      


for (i = 0; i < 5; i++)


0101168E


C7 45 F8 00 00 00 00


mov    dword ptr [ebp-8],  0


01011695


EB 09


jmp     010116A0


01011697


8B 45 F8


mov    eax, dword ptr [ebp-8]


0101169A


83 C0 01


add     eax,1


0101169D


89 45 F8


mov    dword ptr [ebp-8],eax


010116A0


83 7D F8 05


cmp    dword ptr [ebp-8],5


010116A4


7D 10


jge     010116B6


arr[i] = 9;


010116A6


8B 45 F8


mov    eax,dword ptr [ebp-8]


010116A9


C7 04 85 80 95 01 01 09 00 00 00


mov    dword ptr [eax*4+01019580h],  9


010116B4


EB E1


jmp     01011697


return 0;


010116B6


33 C0


xor     eax,eax

上表中除了程序源代码,其它部分中,最左列是指令的地址,中间是机器码,也就是机器最后执行的代码,右列是对应的汇编语言代码。可能初学者看不懂这些汇编代码,没有关系。我们重点看一下这一句:mov   dword ptr
[eax*4 + 01019580h]
, 9 它的功能就是arr[i] = 9,其中eax中存放着变量i的值,4表示每个元素占4个字节,01019580h是数组arr的首地址,为了确认,可以在监视窗口中键入arr或者&arr[0],我们可以看到它们的值等于0x01019580h,如下图所示:

也就是说,在给第i个元素赋值时,先要计算它的地址,即:首地址+i*4,在这个例子中,首地址是01019580h,所以第0个元素存放在以01019580h
开始的四个字节中,第1个元素存放在以01019584h
开始的四个字节中,…,第4个元素存放在以01019590h
开始的四个字节中。计算出地址后,用mov指令将9传递到该地址开始的4个字节中存放。执行完for循环后,查看01019580h开始的内存情况,如下图所示:

可以看到,以0x01019580h开始的连续20个字节中存放着5个9。

从上面看出,当数组元素下标从0开始时,每个元素的地址计算如下:

第0个元素地址:首地址
(首地址 + 0*4)

第1个元素地址:首地址
+ 1*4

第2个元素地址:首地址
+ 2*4

                            第i个元素地址:首地址
+ i*4

当数组元素下标从1开始时,每个元素的地址计算如下:

第1个元素地址:首地址

第2个元素地址:首地址
+(2-1)*4

第3个元素地址:首地址
+(3-1)*4

                            第i个元素地址:首地址
+(i-1)*4

很明显,如果数组元素下标从1开始,每次计算地址时,需要多做一次减法操作。因此,为了提高效率,C语言数组元素下标从0开始。C语言的高效率就是体现在这些点点滴滴中的,需要在学习中慢慢体会!

时间: 2024-10-13 09:40:56

C语言数组元素下标为何从0开始的相关文章

c语言:对10个数组元素依次赋值为0,1,2,3,4,5,6,7,8,9,要求按逆序输出。

对10个数组元素依次赋值为0,1,2,3,4,5,6,7,8,9,要求按逆序输出. 解:程序: #include<stdio.h> int main() { int i, a[10]; for (i = 0; i <= 9; i++) { a[i] = i; } for (i = 9; i >= 0; i--) { printf("%3d", a[i]); } printf("\n"); return 0; } 结果: 9  8  7  6 

[算法]一整型数组,除了0之外,其他不重复,判断数组元素是否相邻

数组元素是非负整数,0可以化为任意正整数,要求时间复杂度为O(n) 觉得很奇怪的题目,遍历一次找到最值相减得到极差就行了,如果极差小于数组长度n,则元素相邻,否则不相邻 bool is_adjacent(int* a, int n){ int min = 65535, max = 0; for(int i = 0; i < n; ++i){ if(!a[i] && a[i] < min){ min = a[i]; } else if(!a[i] && a[i]

C 语言数组

#import <Foundation/Foundation.h> #define knum 5 #define kArr "shuguangnvshen" int main(int argc, const char * argv[]) { //数组:数组是一组具有相同数据类型的成员组成的有序的集合 //格式:类型修饰符 数组名=(赋值运算符) {数组元素}; //访问数组元素:数组名加下标; /* int array[]={12,3,4,8}; 0 1 2 3 array

c语言-数组+字符串处理函数

一.构造类型 基本概念: (1)在C语言中,变量类型除了几种基本类型之外,还有另外一些复杂类型,合称为构造类型. (2)构造类型:是由基本类型构造而成的(如数组.结构体.共同体.枚举型). (3)构造类型的每一个分量是一个变量,它可以是一个简单类型或者构造类型. (4)构造类型的分量的使用方法与简单变量相同 (5)构造类型的分量占用相邻的存储空间. (6)对于构造类型的变量来说,重点是访问其分量的方法. 二.数组 数组概念:按序排列的具有相同类型的变量的集合 (1)用一符号名(数组名)来表示这一

C语言数组实现约瑟夫环问题,以及对其进行时间复杂度分析

尝试表达 本人试着去表达约瑟夫环问题:一群人围成一个圈,作这样的一个游戏,选定一个人作起点以及数数的方向,这个人先数1,到下一个人数2,直到数到游戏规则约定那个数的人,比如是3,数到3的那个人就离开这个游戏:按这样的规则,剩下一个人,游戏就结束,这个人就为赢家.(读者可以试着表达,不认同,直接忽略) 抽象分析 这个人就是一个数据个体,数据结点,数据元素.上面产生的数据结构为:单方向循环的链.可以用链表实现,也可以用数组来实现. 链表到数组的迁移 人(数据元素. 数据结点.数据个体) 结点关系 (

c语言 数组(一维、字符)

//  main.m //  1-16课堂笔记 //讲师:小辉 //笔者:王学文 //  Created by lanouhn on 15/1/16. //  Copyright (c) 2015年 lanouhn. All rights reserved. //数组(一维.字符) #import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { //数组:用于存储 相同数据类型 的有序队列 //数组定义的格

编程题:比较指向数组元素的指针变量和指向数组的指针变量的不同。

#include<stdio.h> void main() {int a[2][3]={1,2,3,4,5,6}; int *p1,(*p2)[3]; /*p1指向数组元素,p2指向包含3个元素的一维数组*/ p1=a[0];p2=a; /*用指向数组元素的指针变量输出二维数组元素*/ for(;p1<a[0]+6;p1++) printf("%4d",*p1); printf("\n"); /*用指向以为数组的指针变量输出二维数组元素*/ for

随机获取数组元素 和 数组元素随机排序

<script type="text/javascript"> //随机取得数组中的一个元素 function Rand(){ var arr=[11,22,33,44]; var a=Math.floor(Math.random()*arr.length);//Math.floor(Math.random()); //Math.floor()方法执行的是向下取整计算,它返回的是小于或等于函数参数,并且与之最接近的整数. //alert(Math.random()*arr.

c++分文件定义,数组元素遍历

1.demo.cpp如下: //遍历数组中的元素,所谓遍历就是 打印数组中的元素,yiban #include<iostream> #include<stdlib.h> #include"Coordinate.h" using namespace  std; int main(void){ Coordinate coor[3];//定义一个坐标,栈的方式访问 coor[0].m_iX=3; coor[0].m_iY=5; Coordinate *p=new Co