【C语言基础考研向】09 一维数组

简介: 数组是一种有序集合,用于存储相同类型的数据,便于统一操作与管理。例如,将衣柜底层划分为10个格子存放鞋子,便于快速定位。在C语言中,数组定义格式为 `类型说明符数组名[常量表达式];`,如 `int a[10];` 表示定义了一个包含10个整数的数组。数组初始化时可以直接赋值,也可以部分赋值,且数组长度必须固定。数组在内存中连续存储,访问时需注意下标范围,避免越界导致数据异常。数组作为参数传递时,传递的是首地址,修改会影响原数组。

1 数组的定义

为了存放鞋子,假设你把衣柜最下面的一层分成了 10 个连续的格子。此时,让他人帮你拿
鞋子就会很方便,例如你可直接告诉他拿衣柜最下面一层第三个格子中的鞋子。同样假设现在我
们有 10 个整数存储在内存中,为方便存取,我们可以借助 C 语言提供的数组,通过一个符号来
访问多个元素。

某班学生的学习成绩、一行文字、一个矩阵等数据的特点如下:
(1)具有相同的数据类型.
(2)使用过程中需要保留原始数据.

C语言为了方便操作这些数据,提供了一种构造数据类型——数组.所谓数组,是指一组具有相同数据类型的数据的有序集合.
一维数组的定义格式为:

类型说明符数组名[常量表达式];

例如:

int a[10];

定义一个整型数组,数组名为a,它有10个元素。
声明数组时要遵循以下规则:
(1)数组名的命名规则和变量名的相同,即遵循标识符命名规则。
(2)在定义数组时,需要指定数组中元素的个数,方括号中的常量表达式用来表示元素的个数,即数组长度.
(3)常量表达式中可以包含常量和符号常量,但不能包含变量。也就是说,C语言不允许对数组的大小做动态定义,即数组的大小不依赖于程序运行过程中变量的值.
以下是错误的声明示例(最新的C标准支持,但是最好不要这么写):

int n;
scanf("%d", &n);/*在程序中临时输入数组的大小*/int a[nl;

数组声明的其他常见错误如下:

float a[0;        /*数组大小为О没有意义*/
int b(2)(3);     /*不能使用圆括号*/
3int k=3, a[kl; /*不能用变量说明数组大小*/

2.一维数组在内存中的存储

语句int mark[100};定义的一维数组 mark在内存中的存放情况如下图所示,每个元素都是
整型元素,占用4字节,数组元素的引用方式是“数组名[下标]",所以访问数组mark 中的元素的方式是 mark[0],mark[1]..,mark[99].注意,没有元素mark[100],因为数组元素是从03开始编号的.

下面介绍一维数组的初始化方法.

(1)在定义数组时对数组元素赋初值.例如,

int a[10]={
   0,1,2,3,4,5,6,7,8,9l;

不能写成

inta[ a[10]={
   0,1,2,3,4,5,6,7,8,9l;

(2)可以只给一部分元素赋值.例如,

int a[10]-{
   0,1,2,3,4};

定义a数组有10个元素,但花括号内只提供5个初值,这表示只给前5个元素赋初值,后5个元素的值为0.

(3)如果要使一个数组中全部元素的值为0,那么可以写为

int a[10]={
   0,0,0,0,0,0,0,0,0,0}int a[10]={
   0};

(4)在对全部数组元素赋初值时,由于数据的个数已经确定,因此可以不指定数组的长度.例如,

int a[]={
   1,2,3,4,5};

3.数组的访问越界

下面借助一个数组的实例来掌握数组元素的赋值、访问越界.下例中给出了该例的全部代码.
【例】一维数组的存储及访问越界.

#finclude <stdlo.h
//数组越界
int main()
{
   
    int a[5]={
   1,2,3,4,5};//定义数组时,数组长度必须固定
    int j=20;
    int i=10;
    a[5]=6;//越界访问
    a[6]=7;//越界访问会造成数据异常
    printf("i=%d\n"",i);//i发生改变
    return 0;
}

数组另一个值得关注的地方是,编译器并不检查程序对数组下标的引用是否在数组的合法范围内.这种不加检查的行为有好处也有坏处,好处是不需要浪费时间对有些已知正确的数组下标进行检查,坏处是这样做将无法检测出无效的下标引用.一个良好的经验法则是:如果下标值是通过那些已知正确的值计算得来的,那么就无须检查;如果下标值是由用户输入的数据产生的,那么在使用它们之前就必须进行检查,以确保它们位于有效范围内.


4.数组的传递

#include <stdio.h>
//一维数组的传递,数组长度无法传递给子函数//C语言的函数调用方式是值传递
vold print(int b[],int len)
{
   
    int i;
    for(i=O;i<len;i++)
    {
   
        printf("%3d",b[i]);
    }
    b[4]=20;//在子函数中修改数组元素
    printf( "\n");
}
//数组越界
//一维数组的传递
#define N 5
int main()
{
   
    int a[5]={
   1,2,3,4,5};//定义数组时,数组长度必须固定print(a,5);
    printf("e[4]=%d\n",a[4]);//a[4]发生改变
    return 0;
}

进入print函数,这时会发现数组b的大小变为8字节,==这是因为一维数组在传递时,其长度是传递不过去的,所以我们通过len来传递数组中的元素个数==.实际数组名中存储的是数组的首地址,在调用函数传递时,是将数组的首地址给了变量b (其实变量b是指针类型,具体原理会在指针节讲解),在b[的方括号中填写任何数字都是没有意义的。这时我们在print 函数内修改元素b[4]=20,可以看到数组b的起始地址和 main 函数中数组a的起始地址相同,即二者在内存中位于同一位置,当函数执行结束时,数组a中的元素a[4]就得到了修改.

相关文章
|
5天前
|
存储 C语言 数据格式
【C语言基础考研向】03混合运算和printf讲解
本文分为两部分。第一部分介绍了C语言中的混合运算与类型强制转换的重要性,通过实例展示了当整型数进行除法运算且结果为小数时,必须使用类型转换才能正确存储浮点数结果。第二部分详细讲解了`printf`函数的功能与使用方法,包括格式化输出不同类型数据的基本语法,并通过具体示例演示了如何利用字段宽度和对齐方式来控制输出格式,帮助读者更好地理解和掌握输出格式的控制技巧。
21 10
|
5天前
|
C语言
【C语言基础考研向】05 scanf读取标准输入超详解
本文详细解析了C语言中`scanf`函数的工作原理及常见问题。首先介绍了`scanf`如何处理标准输入,并通过示例说明了为何有时会出现阻塞现象及其解决办法。接着探讨了当输入包含多种数据类型时,特别是字符型数据的处理方式,强调了格式控制的重要性,并给出了正确的输入格式示例。通过正确配置,可以避免因空格和换行符导致的问题,确保数据准确读取。
22 10
|
5天前
|
程序员 C语言
【C语言基础考研向】06运算符与表达式
本文介绍了C语言中的运算符分类、算术运算符及表达式、关系运算符与表达式以及运算符优先级等内容。首先概述了13种运算符类型,接着详细说明了算术运算符的优先级与使用规则,以及关系运算符和表达式的真假值表示,并给出了C语言运算符优先级表。最后附有课后习题帮助巩固理解。
40 10
|
5天前
|
存储 C语言
【C语言基础考研向】02 数据类型-常量-变量
本文介绍了编程中的基本概念,包括数据类型分类、常量与变量的定义及使用。首先概述了四大类数据类型:基本类型(整型、浮点、字符型)、构造类型(数组、结构体)、指针类型和空类型。接着阐述了常量与变量的区别及命名规则,并详细说明了整型、浮点型和字符型数据的特点与应用。最后总结了常见的易错点,如字符串与字符常量的区别及浮点数的默认输出格式。
|
5天前
|
存储 C语言
【C语言基础考研向】04整型进制转换
本文介绍了计算机中整型常量的不同进制表示,包括二进制、八进制、十六进制和十进制,并解释了它们之间的转换方法。以一个32位整型数为例,展示了其在不同进制下的表示形式及计算方法,特别指出在内存观察中常用十六进制,同时提到了小端存储方式对数据的影响。
|
5天前
|
C语言
【C语言基础考研向】08判断语句与循环语句
本文介绍了C语言中的关键编程概念:首先解析了关系表达式与逻辑表达式的优先级及计算过程;接着详细说明了`if-else`语句的使用方法及其多分支和嵌套应用;然后讲解了`while`循环与`for`循环的语法和注意事项;最后介绍了`continue`和`break`语句在控制循环中的作用和示例代码。
|
5天前
|
存储 编译器 C语言
【C语言基础考研向】07逻辑运算符与赋值运算符
本文介绍了C语言中的逻辑运算符与逻辑表达式、赋值运算符以及求字节运算符`sizeof`。逻辑运算符包括`!`(逻辑非)、`&&`(逻辑与)和`||`(逻辑或),其优先级规则与数学运算符类似。通过示例展示了如何用这些运算符判断闰年及逻辑非的运算方向。此外,文章还解释了左值与右值的概念及其在赋值运算中的应用,并介绍了复合赋值运算符的使用方法,如加后赋值`+=`和乘后赋值`*=`。最后,通过`sizeof`运算符示例展示了如何获取变量的字节大小。
|
5天前
|
存储 C语言
【C语言基础考研向】10 字符数组初始化及传递和scanf 读取字符串
本文介绍了C语言中字符数组的初始化方法及其在函数间传递的注意事项。字符数组初始化有两种方式:逐个字符赋值或整体初始化字符串。实际工作中常用后者,如`char c[10]=&quot;hello&quot;`。示例代码展示了如何初始化及传递字符数组,并解释了为何未正确添加结束符`\0`会导致乱码。此外,还讨论了`scanf`函数读取字符串时忽略空格和回车的特点。
|
5天前
|
存储 Serverless C语言
【C语言基础考研向】11 gets函数与puts函数及str系列字符串操作函数
本文介绍了C语言中的`gets`和`puts`函数,`gets`用于从标准输入读取字符串直至换行符,并自动添加字符串结束标志`\0`。`puts`则用于向标准输出打印字符串并自动换行。此外,文章还详细讲解了`str`系列字符串操作函数,包括统计字符串长度的`strlen`、复制字符串的`strcpy`、比较字符串的`strcmp`以及拼接字符串的`strcat`。通过示例代码展示了这些函数的具体应用及注意事项。
|
8天前
|
存储 人工智能 C语言
C语言程序设计核心详解 第六章 数组_一维数组_二维数组_字符数组详解
本章介绍了C语言中的数组概念及应用。数组是一种存储同一类型数据的线性结构,通过下标访问元素。一维数组定义需指定长度,如`int a[10]`,并遵循命名规则。数组元素初始化可使用 `{}`,多余初值补0,少则随机。二维数组扩展了维度,定义形式为`int a[3][4]`,按行优先顺序存储。字符数组用于存储字符串,初始化时需添加结束符`\0`。此外,介绍了字符串处理函数,如`strcat()`、`strcpy()`、`strcmp()` 和 `strlen()`,用于拼接、复制、比较和计算字符串长度。