回首页 回首页 ◎ 设为首页  
◎ 收藏本站  
◎ 给我留言  
  
  首 页  C/C++教程  C++之父的FAQ  C/C++动向  C/C++源代码  C/C++误区  Unix/Linux  下载中心  乱七八糟  蚂蚁的Blog  
  当前位置:首 页 >> C/C++教程 >> C 语言基础教程 >> 29. 数组基础(下)
最 近 更 新
54. goto 语句
53. switch 语句推荐
52. continue 和 break
51. 条件运算符(?:)
50. if 语句嵌套推荐
49. 逻辑运算符推荐
48. 在循环中使用 if 语句推荐
47. if 和 else 连用推荐
46. if 语句
45. 循环应用实例 2
最 新 推 荐
53. switch 语句推荐
50. if 语句嵌套推荐
49. 逻辑运算符推荐
48. 在循环中使用 if 语句推荐
47. if 和 else 连用推荐
44. 循环应用实例 1推荐
43. 循环嵌套推荐
40. for 循环推荐
37. 关系运算符推荐
36. while 循环推荐
热 门 排 行
2. 第一个 C 程序推荐
31. 预处理指令 #define..推荐
1. C 语言简介
11. 基本数据类型:整型..推荐
24. 运算符的优先级和结..推荐
5. 如何编写函数
30. 字符串字面量推荐
13. 标识符命名规则
36. while 循环推荐
7. 第三个 C 程序推荐
站 内 搜 索

Web stdcpp.cn
关键词

搜索方式

搜索范围

精确匹配
广 告

29. 数组基础(下)


来源:蚂蚁的 C/C++ 标准编程 作者:antigloss 等级:强烈推荐
发布于2006-04-01 13:28 被读4188次 【字体:

1. 指派初始值(Designated Initializers)

    指派初始值这个特性是 C99 增加的,它允许我们直接初始化数组中特定的元素。C99 以前,如果我们要初始化数组中的某个元素,如第三个元素,必须同时初始化它之前的元素。例如:

        int iarr[10] = { 0, 0, 300 };

而 C99 中,我们可以这样初始化特定的元素:

        int iarr[10] = { [2] = 300 };  /* 指派初始化 iarr[2] 为 300 */

其余的元素都会被初始化为 0 。下面我们来看一个小程序。

        #include <stdio.h>

        int main(void)
        {
            int iarr[5] = { 6, 3, [3] = 1, 5, [1] = 8};
    
            printf("%d\n", iarr[0]);
            printf("%d\n", iarr[1]);
            printf("%d\n", iarr[2]);
            printf("%d\n", iarr[3]);
            printf("%d\n", iarr[4]);

            return 0;
        }

输出为:

        6
        8
        0
        1
        5

从中可以看出两点:

    A. 如果指派初始值后面还有值,则后面的值会被用于初始化后续的元素。上例中,
       iarr[3] 被初始化为 1 ,它后续的元素 iarr[4] 被初始化为 5。

    B. 如果初始化列表中多次出现对某元素的初始化,则以最后一次为准。上例中,
       iarr[1] 先被初始化为 3,然后被 [1] = 8 指派初始化为 8。


2. 给数组元素赋值

    我们可以利用下标给特定的元素赋值。例如:

        int iarr[5];
        iarr[0] = 100;  /* 赋值给第一个元素 */
        iarr[4] = 120;  /* 赋值给第五个元素 */
        iarr[2] = 180;  /* 赋值给第三个元素 */

C 不允许直接使用数组对别的数组进行赋值,也不允许使用初始化列表对数组进行赋值。例如:

        int iarr_1[5] = { 1, 2, 3, 4, 5 };   /* 正确 */
        int iarr_2[5];

        iarr_2 = iarr_1;                     /* 错误! */
        iarr_2[5] = { 3, 4, 5, 6, 7 };       /* 错误! */
        iarr_2[5] = iarr_1[5];               /* 越界! */

最后一个语句发生了越界!因为这两个数组都只有 5 个元素,而使用下标 5 访问的是第六个元素!

 

3. 数组界限(array bounds)

    使用下标时,我们必须确保下标没有越界。例如:

        int iarr[46];

这个数组的下标范围是 0 到 45,确保下标没有超出这个范围是我们的责任,因为编译器不会对下标越界进行检测!

    C 标准没有定义下标越界的后果,也就是说,当我们写的程序中出现下标越界的问题,程序可能正常工作,也可能异常退出,还有可能出现其它奇怪的情况。

        #include <stdio.h>

        int main(void)
        {
            int var_1 = 20;
            int arr[5];
            int var_2 = 40;

            printf("var_1: %d, var_2: %d\n", var_1, var_2);

            arr[-1] = -1;
            arr[5]  =  5;

            printf("%d  %d\n", arr[-1], arr[5]);
            printf("var_1: %d, var_2: %d\n", var_1, var_2);

            return 0;
        }

上述程序使用 Dev-C++ 4.9.9.2 编译运行的输出为:

        var_1: 20, var_2: 40
        -1  5
        var_1: 20, var_2: -1

可见,下标越界可能改变其它变量的值。这是因为 gcc(dev-c++ 使用的 C 编译器)把 var_2 保存于数组 arr 之前的内存空间,所以对 arr[-1] 赋值正好改变了 var_2 的值。不同的编译器编译运行该程序可能会有不同的输出,也可能会异常退出。

    C 语言的哲学是信任程序员,而且不检测越界程序运行更快。程序编译时有些下标的值仍然是不可知的,所以如果要检测下标越界的话,编译器必须在生成的目标代码中加入额外的代码用于程序运行时检测下标是否越界,这就会导致程序运行速度下降。故而,为了运行效率,C 不检测下标是否越界。


4. 指定数组元素数目

    C99 之前,声明数组时,[] 中的值必须是大于零的整数常量。C99 中,声明数组时,[] 中可以是变量。这就是所谓的变长数组(variable-length array,简称 VLA)。声明 VLA 时,不能对其进行初始化。在后续的教程中,我会对 VLA 进行详细讲解。

        int n = 99;
        double dbl_1[4];          /* 正确 */
        double dbl_2[8/2 + 4];    /* 正确 */
        int    iar_1[-5];         /* 错![] 中的值必须大于 0 */
        int    iar_2[0];          /* 错![] 中的值必须大于 0 */
        int    iar_3[9.2];        /* 错![] 中的值必须是整数类型 */
        char   ch[n];             /* C99 之前不支持! */

参考资料:C Primer 5th Edition
          The C Programming Language 2nd Edition
          C99 标准

本文版权归 蚂蚁的 C/C++ 标准编程 以及 作者 antigloss 共同所有,转载请注明原作者和出处。谢谢。



相关专题:C 语言数据类型
38. 布尔类型再探讨
30. 字符串字面量

上一篇:28. 数组基础(上)
下一篇:30. 字符串字面量

共有评论 6 条 网友评分 3分 查看全部评论

游客:lain
评分:4
期待详细讲讲VLA
游客:zhanhzhi
评分:2
可惜我只学的是C++
游客:菜鸟爱CPP
评分:5
VLA类似于C#里面的ArrayList,我自己写了个ArrayList类
游客:chaifengdi
评分:0
请问一下,c中没有二维或者更多的数组么?
游客:antigloss
评分:0
有。
二维
int arr[2][2]
三维
int arr[3][3][3]
... ...
游客:stillunix
评分:5
期待中!你能讲一下类和其他的如虚函数之类的吗?

查看全部评论

【发表评论】 评分:1分 2分 3分 4分 5分


验证码:

Powered By Www.Xydw.COM Ver1.14 管理
Copyright © 2005-2006 蚂蚁的 C/C++ 标准编程 All Right Reserved. XCMS
粤ICP备06014124号   站长:Antigloss