数组(以一维数组为例)
基本概念
例如:
int a[100];就像字符串的写法 char a[100];一样,数组也是按照这样。
int规定数组的类型,a是变量的名称,[100]则代表了这个数组里有100个变量。也就是:
<类型>变量名称[元素数量]而且这里的元素数量必须是整数。数组在创建之后,就不能改变大小了。
内存存储
在内存中,数组的单元是依次排列的,如果是int形的数组就可以用指针运算的形式获得后面一位的元素。
动态数组大小
数组中括号里的数字也可以用变量代替,比如:
int a;int b[100];int c = 0;double sum;while(x != -1) { b[c] = a; sum += a; c++; scanf("%d", a);}printf("%d", sum / c);这是一个输入100个以内的数字求出平均数,并输入-1时终止输入的程序。
数组与普通变量的区别
示例对比
程序1(使用数组):
#include<stdio.h>int main(){ int a, b, c; scanf("%d", &a); double sum = 0; b = a; c = 1; while (c != n) { scanf("%d", &a); sum += a; } printf("%d", sum / a); return 0;}程序2(使用数组记录):
用数组的程序记录下了每一个输入的变量,而第二个程序则在每次的计算中就抹除了输入的变量,第一个程序在运行结束之后仍旧可以查看每一次输入的数字,而第二个程序到最后的结果只能求出的平均数。
数组的基本操作
数组输出
数组也是可以直接输出的,比如像这样:
printf("%d", number[i]);这样就会输出符合条件的所有number。
数组运算
数组运算也可以出现在赋值运算里,象是这样:
a[1] = a[2] + 3;这个表达式的意思是:读出a[2]的值,并与3相加,作为a[1]的值。
下标(索引)
在使用数组时,[]内的数字就是下标,也叫索引。象是这样:
int a[100];scanf("%d", &a[2]); // 表示要写入a[2]中去重要提示
数组计数是从0开始计数,例如 int a[100] 实际上这个数组里有100个元素。a[0]是第一个元素,a[99]是最后一个元素。
数组越界问题
编译器检查
编译器不会检查数组下表是否越界,无论是对数组单元读还是写。不同的编译器或是运行环境对数组的检查不一样,所以很可能发生这种错误:
在他的编译器上能运行,在你的编译器运行不了,上一次能打开,这一次就打不开了。
这种问题就有可能出现在因为数组使用时越界。
越界示例
int a[10];a[10] = 1; // 这里的a[10]实际上就超出了数组的范围printf("%d", a[10]); // 但是不会报错,而是会照着错误的情景运行下去所以一定要养成检查数组的习惯。
动态数组
为了获取固定的数组范围,我们可以使用这样的代码:
int count;scanf("%d", &count);int a[count];让用户先输入数字的范围,再根据输入的数字来创建数组的大小。
当然,你也可以写出一个长度为0的数组,像是这样:
int a[0];但是,这个数组是无用的。
数组初始化
数组也需要初始化,通常我们用循环的方式来让数组进行初始化,比如这样:
int a[10];int i;for(i = 0; i < 10; i++) { count[i] = 0;}这样操作之后,数组的每一项的值都会变为0,也就完成了初始化。
(如果用集成初始化的方式,可以变得更简单)
int a[10] = {0};这样使用了集成初始化之后,a里的每一个元素的值都是0了!
获取数组长度
如果想要知道一个数组里有多少个元素也很简单,需要用到sizeof函数(显示占据多少个字节数),像是这样:
sizeof(a) / sizeof(a[1]);这个代码所表达的意思是:用这个数组所占据的总字节数除以一个元素占据的字节数,就可以求出来一共有多少个元素了——因为同类型的变量所占据的字节数是一样大的。
数组赋值
错误示例
数组变量是不能赋值的,比如这样是不可以的:
int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};int b[10] = a; // 这样是不行的正确方法
想要赋值必须使用遍历数组的方式,比如这样:
for(i = 0; i < length; i++) { b[i] = a[i];}通过循环的方式来让数组b的每一项都等于数组a的每一项。
函数与数组
在调用函数的时候,不能给出数组的大小,即a[]的中括号里不能有数字。这意味着你不能使用sizeof函数来计算元素的个数,必须传入另一个参数来充当数组的大小。
数组地址
如果直接输出数组的地址,像是这是这样:
int a[10];printf("%p", a);得到的值和a[0]的地址是一样的。
实际上,数组的地址就是起始项的地址,占据的字节就是多少项4,所以取得起始项的地址加上4x项就是最后一项的地址。