🍌数组
2021-1-22
| 2023-8-2
0  |  阅读时长 0 分钟
type
status
date
slug
summary
tags
category
icon
password
Property
 

 
数组由数据类型相同的一系列元素组成。需要使用数组时,通过声明数组告诉编译器数组中内含多少元素和这些元素的类型。编译器根据这些信息正确地创建数组。普通变量可以使用的类型,数组元素都可以用。
要访问数组中的元素,通过使用数组下标数(索引)表示数组中的各元素。数组元素的编号从0开始,candy[0]表示candy数组的第1个元素,candy[364]表示第365个元素,也就是最后一个元素。
 

初始化数组

用以逗号分隔的值列表(用花括号括起来)来初始化数组,各值之间用逗号分隔,在逗号和值之间可以使用空格
 
 

使用const声明数组

有时需要把数组设置为只读。这样,程序只能从数组中检索值,不能把新值写入数组。要创建只读数组,应该用const声明和初始化数组。
和普通变量一样,应该使用声明来初始化const 数据,因为一旦声明为const,便不能再给它赋值
 

部分初始化数组

初始化列表中的项数应与数组的大小一致,如果不一致会怎样?
如果不初始化数组,数组元素和未初始化的普通变量一样,其中储存的都是垃圾值;但是,如果部分初始化数组,剩余的元素就会被初始化为0。
 
如果初始化数组时省略方括号中的数字,编译器会根据初始化列表中的项数来确定数组的大小。
由于人工计算容易出错,所以让计算机来计算数组的大小。sizeof运算符给出它的运算对象的大小。sizeof days是整个数组的大小(以字节为单位),sizeof day[0]是数组中一个元素的大小。整个数组的大小除以单个元素的大小就是数组元素的个数。
 

指定初始化器

C99 增加了一个新特性:指定初始化器。利用该特性可以初始化指定的数组元素。
例如,只初始化数组中的最后一个元素。对于传统的C初始化语法,必须初始化最后一个元素之前的所有元素,才能初始化它:
 
而C99规定,可以在初始化列表中使用带方括号的下标指明待初始化的元素:
指定初始化器的两个重要特性:
  • 如果指定初始化器后面有更多的值,如该例中的初始化列表中的片段:[4] = 31,30,31,后面这些值将被用于初始化指定元素后面的元素。
  • 如果再次初始化指定的元素,那么最后的初始化将会取代之前的初始化。例如,初始化列表开始时把days[1]初始化为28,但是days[1]又被后面的指定初始化为29。
 

给数组元素赋值

声明数组后,可以借助数组下标(或索引)给数组元素赋值。
C 不允许把数组作为一个单元赋给另一个数组,除初始化以外也不允许使用花括号列表的形式赋值。
 
 

数组边界

在使用数组时,要防止数组下标超出边界。也就是说,必须确保下标是有效的值
C信任程序员的原则。不检查边界,C 程序可以运行更快。编译器没必要捕获所有的下标错误,因为在程序运行之前,数组的下标值可能尚未确定。为安全起见,编译器必须在运行时添加额外代码检查数组的每个下标值,这会降低程序的运行速度。C 相信程序员能编写正确的代码,这样的程序运行速度更快。
 
 

指定数组的大小

在C99标准之前,声明数组时只能在方括号中使用整型常量表达式。所谓整型常量表达式,是由整型常量构成的表达式。sizeof表达式被视为整型常量,但是(与C++不同)const值不是。另外,表达式的值必须大于0:
以前支持C90标准的编译器不允许后两种声明方式。而C99标准允许这样声明,这创建了一种新型数组,称为变长数组或简称 VLA。
 

多维数组

notion image
 
 
初始化二维数组
初始化时也可省略内部的花括号,只保留最外面的一对花括号。只要保证初始化的数值个数正确。但是如果初始化的数值不够,则按照先后顺序逐行初始化,直到用完所有的值。后面没有值初始化的元素被统一初始化为0。
notion image
 
 

变长数组(VLA)

要创建一个能处理任意大小二维数组的函数,比较繁琐(必须把数组作为一维数组传递,然后让函数计算每行的开始处)鉴于此,C99新增了变长数组(variable-length array),允许使用变量表示数组的维度。
变长数组有一些限制。变长数组必须是自动存储类别,这意味着无论在函数中声明还是作为函数形参声明,都不能使用static或extern存储类别说明符。而且,不能在声明中初始化它们。最终,C11把变长数组作为一个可选特性,而不是必须强制实现的特性。
变长数组中的“变”不是指可以修改已创建数组的大小。一旦创建了变长数组,它的大小则保持不变。这里的“变”指的是:在创建数组时,可以使用变量指定数组的维度。
 
首先,要声明一个带二维变长数组参数的函数,如下所示:
注意前两个形参(rows和cols)用作第3个形参二维数组ar的两个维度。因为ar的声明要使用rows和cols,所以在形参列表中必须在声明ar之前先声明这两个形参。
 
C99/C11标准规定,可以省略原型中的形参名,但是在这种情况下,必须用星号来代替省略的维度:
其次,该函数的定义如下:
该函数除函数头与传统的C函数不同外,还把符号常量COLS替换成变量cols。这是因为在函数头中使用了变长数组。由于用变量代表行数和列数,所以新的sum2d()现在可以处理任意大小的二维int数组,如程序所示。但是,该程序要求编译器支持变长数组特性。另外,该程序还演示了以变长数组作为形参的函数既可处理传统C数组,也可处理变长数组。
 
notion image
 
 
需要注意的是,在函数定义的形参列表中声明的变长数组并未实际创建数组。和传统的语法类似,变长数组名实际上是一个指针。这说明带变长数组形参的函数实际上是在原始数组中处理数组,因此可以修改传入的数组。下面的代码段指出指针和实际数组是何时声明的:
调用twoset()时,ar成为指向thing[0]的指针,temp被创建为10×6的数组。因为ar和thing都是指向thing[0]的指针,ar[0][0]与thing[0][0]访问的数据位置相同。
 
 
是否可以在声明数组时使用const变量?
C90标准不允许(也可能允许)。数组的大小必须是给定的整型常量表达式,可以是整型常量组合,如20、sizeof表达式或其他不是const的内容。由于C实现可以扩大整型常量表达式的范围,所以可能会允许使用const,但是这种代码可能无法移植。 C99/C11 标准允许在声明变长数组时使用 const 变量。所以该数组的定义必须是声明在块中的自动存储类别数组。
变长数组还允许动态内存分配,这说明可以在程序运行时指定数组的大小。普通 C数组都是静态内存分配,即在编译时确定数组的大小。由于数组大小是常量,所以编译器在编译时就知道了。
  • C
  • 更改主调函数中的变量指针
    目录