热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C语言第八章数组

文章目录1数组定义2一维数组2.1一维数组的定义2.2一维数组初始化2.3一维数组赋值2.4一维数组引用3二维数组3.1二维数组的定义3.2二维数组初始化4向函数传递数组4.1一维




文章目录


  • 1 数组定义
  • 2 一维数组
    • 2.1 一维数组的定义
    • 2.2 一维数组初始化
    • 2.3 一维数组赋值
    • 2.4 一维数组引用

  • 3 二维数组
    • 3.1 二维数组的定义
    • 3.2 二维数组初始化

  • 4 向函数传递数组
    • 4.1 一维数组传递
    • 4.2 二维数组传递
    • 4.3 将数组名作为参数传递时


1 数组定义

数组是一组相同类型的数据的集合
数组中的元素通过下标来区分
一维数组:储存线性数据
二维数组:用来储存平面信息,
三维数组:储存空间信息或更复杂的时空信息。


2 一维数组

2.1 一维数组的定义

数组声明格式:


类型说明符 数组名[常量表达式]
类型说明符:除void以外的任何类型
定义数组大小,即元素个数。只允许字面常量或符号常量不允许是变量



  • 例如

int x[5];
// 或者
#define N 5
int x[N];

  • 数组不能动态定义,数组的大小必须在定义时就确定

2.2 一维数组初始化


  • 初始化方式


    • 将数组中所有元素初始化为0(偷懒),事实上只给第一个元素赋了值

      int a[10] = {0};


    • 如果是赋予不同的值,用逗号分开即可

      int x[5]={20, 4, 16, 37, 9};


    • 对部分元素赋初值,长度不能省,其余自动初始化为0

      int z[6]={13, 24, 9};


    • 对全部元素赋初值时可以不指定数组长度。

      double y[ ]={2.8, 10.4};


    • c99增加一种特性,可以指定初始化元素

      int a[10] = {[3] = 3, [5] = 5}


    • 当数组声明为静态数组或全局数组时,系统会对所有数组元素自动初始化为0

      static int a[5]


  • 注意事项:


    • 注意下标(比如数组长度为5,下标是0~4)
    • 记得初始化,一定要先赋值再输出,不然数组越界有时不会报错但会产生乱七八糟的东西
  • 我们常需要用循环来访问数组


    • 从0开始循环非常好的解决了数组越界的问题

int main(void)
{
int a[5]; /*定义大小为5的数组*/
int index;

for(index = 0; index <5; index++)
{
printf("%d\n", a[index]);/*循环输出*/
}

return 0;
}

2.3 一维数组赋值

/* 定义大小为3的整型数组并初始化 */
int a[3] = {11, 22, 33};
a[1] = 100; /* 正确,a[1]赋值为100 */
a[3] = 200; /* 错误,下标越界 */
a[10] = 300; /* 错误,下标越界 */

2.4 一维数组引用


数组名[下标表达式]
下标表达式必须是整数,且大于等于0;
数组名代表数组首地址,对数组不能整体输入和输出。



3 二维数组

3.1 二维数组的定义

二维数组的定义:
以二维表形式存储数据。(行、列概念)


类型说明符 数组名[常量表达式][常量表达式]
行数(第一维)列数(第二维)


例如: float a[3][4];
二维数组在内存中按行存储


3.2 二维数组初始化


  1. 按行存取

int b[2][3]={{1,2,3},{4,5,6}};
或者
也可写成:int b[2][3]={1,2,3,4,5,6}; (按数组排列顺序对各元素赋初值)



  1. 对部分元素赋初值

int b[3][2]={0};//全部元素初始化为0
int a[2][4]={ {1},{5} }; //注意赋值里是2行的意思,实际两行的下标分别为0和1



  1. 不指定第一维长度的初始化
    • 第二维长度必须指定!

int a[][3]={{1,2,3},{4,5},{6},{0}};
int a[][4]={1,2,3,4,5,6,7,8}; (根据列数和元素总数可计算行数)
int a[][4]={ {0,0,3},{ },{0,10}};



4 向函数传递数组

4.1 一维数组传递


  • 数组名代表数组的首地址。
  • 数组名也可以作实参和形参,传递的是数组的起始地址
  • 调用函数时,实参必须是数组名
  • 例:编写函数实现一维数组的输入输出。


  1. 输入函数的原型为:
    void input(int a[], int n);
    其中第一个参数为int数组,第二个参数为数组的大小。
    调用:input(a,size);
  2. 输出函数的原型为:
    void print(int [], int);
    其中第一个参数为int数组,第二个参数为数组的大小。注意在函数的原型说明中,可以去掉形参名。
    调用:print(a,size);


  1. tips

  • 当函数原型是这两种写法时

    void func(int p[], int n)
    void func(int p[10], int n)



    • 上面的两个例子,好像定义了一个数组,甚至元素个数都加进去了,实际上这两种形式的数组定义都是假象。两者都不会创建一个数组出来,最终还是会转换为指针*p
    • int p[10]这种形式只能说明函数期望用户传递的数组有 10个元素,并不意味着数组只能有 10 个元素,真正传递的数组可以有少于或多于10 个的元素。
    • 参数的传递本质上是一次赋值的过程,赋值就是对内存进行拷贝。而数组中数据的数量没有限制,可能非常多,对它们进行内存拷贝有可能是一个漫长的过程,会严重拖慢程序的效率,为了规避上述情况,C语言没有从语法上支持数据集合的直接赋值。

4.2 二维数组传递


  • 在函数定义时,形式参数可以明确指定二维数组的行数和列数,也可以不指定行数,但必须指定二维数组的列数

int MA(int a[3][10]);
int MA(int a[][10]);



  • 实参数组的列数必须和形参数组的列数相同!

4.3 将数组名作为参数传递时


  1. 在普通变量或下标变量作函数参数时,形参变量和实参变量是由编译系统分配的两个不同的内存单元。在函数调用时发生的值传送是把实参变量的值赋予形参变量。在用数组名作函数参数时,不是进行值的传送,即不是把实参数组的每一个元素的值都赋予形参数组的各个元素。因为实际上形参数组并不存在,编译系统不为形参数组分配内存。那么,数据的传送是如何实现的呢?在我们曾介绍过,数组名就是数组的首地址。因此在数组名作函数参数时所进行的传送只是地址的传送,也就是说把实参数组的首地址赋予形参数组名。形参数组名取得该首地址之后,也就等于有了实在的数组。实际上是形参数组和实参数组为同一数组共同拥有一段内存空间。因此当形参数组发生变化时,实参数组也随之变化
  2. 声明形参数组并不意味着真正建立一个包含若干元素的数组,在调用函数时也不它分配存储单元,只是用array[]这样的形式表示array是一维数组名,以接收实参传来的地址。因此array[]中方括号内的数值并无实际作用,编译系统对一维数组方括号内的内容不予处理。形参一维数组的声明中可以写元素个数,也可以不写
  3. 多维数组也可以作为函数的参数。在函数定义时对形参数组可以指定每一维的长度,也可省去第一维的长度。因此,以下写法都是合法的:int MA(int a[3][10]);或int MA(int a[][10]);
  4. 看了这篇数组名作为参数传递给函数就可以解释第五点
  5. 在函数形参表中,允许不给出形参数组的长度,或用一个变量来表示数组元素的个数。例如,可以写为:

void nzp(int a[])
或写为
void nzp( int a[], int n )
其中形参数组a没有给出长度,而由n值动态地表示数组的长度。n的值由主调函数的实参进行传送。
数组作为函数参数时,最好将数组大小也作为一个函数参数




推荐阅读
  • 本问题探讨了在特定条件下排列儿童队伍的方法数量。题目要求计算满足条件的队伍排列总数,并使用递推算法和大数处理技术来解决这一问题。 ... [详细]
  • 采用IKE方式建立IPsec安全隧道
    一、【组网和实验环境】按如上的接口ip先作配置,再作ipsec的相关配置,配置文本见文章最后本文实验采用的交换机是H3C模拟器,下载地址如 ... [详细]
  • 深入解析Java枚举及其高级特性
    本文详细介绍了Java枚举的概念、语法、使用规则和应用场景,并探讨了其在实际编程中的高级应用。所有相关内容已收录于GitHub仓库[JavaLearningmanual](https://github.com/Ziphtracks/JavaLearningmanual),欢迎Star并持续关注。 ... [详细]
  • 实用正则表达式有哪些
    小编给大家分享一下实用正则表达式有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下 ... [详细]
  • 开发笔记:9.八大排序
    开发笔记:9.八大排序 ... [详细]
  • C语言基础入门:7个经典小程序助你快速掌握编程技巧
    本文精选了7个经典的C语言小程序,旨在帮助初学者快速掌握编程基础。通过这些程序的实践,你将更深入地理解C语言的核心概念和语法结构。 ... [详细]
  • PHP 过滤器详解
    本文深入探讨了 PHP 中的过滤器机制,包括常见的 $_SERVER 变量、filter_has_var() 函数、filter_id() 函数、filter_input() 函数及其数组形式、filter_list() 函数以及 filter_var() 和其数组形式。同时,详细介绍了各种过滤器的用途和用法。 ... [详细]
  • 本题探讨了在一个有向图中,如何根据特定规则将城市划分为若干个区域,使得每个区域内的城市之间能够相互到达,并且划分的区域数量最少。题目提供了时间限制和内存限制,要求在给定的城市和道路信息下,计算出最少需要划分的区域数量。 ... [详细]
  • 本文详细探讨了HTML表单中GET和POST请求的区别,包括它们的工作原理、数据传输方式、安全性及适用场景。同时,通过实例展示了如何在Servlet中处理这两种请求。 ... [详细]
  • 本文探讨了在C++中如何有效地清空输入缓冲区,确保程序只处理最近的输入并丢弃多余的输入。我们将介绍一种不阻塞的方法,并提供一个具体的实现方案。 ... [详细]
  • 深入解析Redis内存对象模型
    本文详细介绍了Redis内存对象模型的关键知识点,包括内存统计、内存分配、数据存储细节及优化策略。通过实际案例和专业分析,帮助读者全面理解Redis内存管理机制。 ... [详细]
  • 深入解析for与foreach遍历集合时的性能差异
    本文将详细探讨for循环和foreach(迭代器)在遍历集合时的性能差异,并通过实际代码示例和源码分析,帮助读者理解这两种遍历方式的不同之处。文章内容丰富且专业,旨在为编程爱好者提供有价值的参考。 ... [详细]
  • JavaScript 基础语法指南
    本文详细介绍了 JavaScript 的基础语法,包括变量、数据类型、运算符、语句和函数等内容,旨在为初学者提供全面的入门指导。 ... [详细]
  • 本文详细解析了Java中hashCode()和equals()方法的实现原理及其在哈希表结构中的应用,探讨了两者之间的关系及其实现时需要注意的问题。 ... [详细]
  • 本题来自WC2014,题目编号为BZOJ3435、洛谷P3920和UOJ55。该问题描述了一棵不断生长的带权树及其节点上小精灵之间的友谊关系,要求实时计算每次新增节点后树上所有可能的朋友对数。 ... [详细]
author-avatar
zhj808008
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有