数组知识点汇总

目录

一、一维数组

1、数组的概念

2、数组的使用方法

2.1 数组的定义

2.2 数组元素的引用

3、数组元素赋初值

​​​​​​​4、使用数组处理数据的特点

5、一维数组例题

二、二维数组

​​​​​​​1、二维数组

2、二维数组的内存映像图

​​​​​​​3、二维数组赋初值

4、二维数组的输出

三、字符数组与字符串

1、字符数组的定义

2、字符数组初始化

3、字符数组的引用

4、字符串和字符串结束标志

5、字符串与字符数组的关系

6、字符数组的输入输出


一、一维数组

​​​​​​​1、​​​​​​​​​​​​​​数组的概念

多个变量,共同使用同一变量名称,并用“下标”加以区分。

eg:

int  score[50];

score[1]、score[35]……

[1]称为下标;

数组的每一个元素都是同类型的变量;通常将数组中的每一个变量称为“元素”;数组元素的下标是从0开始的!

数组的每一个元素都是一个独立的变量。

2、数组的使用方法

2.1 数组的定义

数组与变量一样,都必须“先定义,方可引用”;定义数组的语句必须出现在所有有效语句之前。

数组定义的语法:type arrayName[非浮点常量(表达式)];

数组定义语句中[]里的内容表示数组元素个数只能用char、short、int、long类型的常量或简单常量表达式,不能使用float、double类型,也不能使用变量或由变量组成的表达式!

 

定义数组的语句,与数组元素引用的语句,采用不同的语法和原则,绝对不能混用!

2.2 数组元素的引用

int  a[10];    // 定义了一个拥有10个int元素的数组a;

数组a中有10个元素,分别是:   a[0]、a[1]、a[2]、……、a[9]

拥有n个元素的数组,其下标取值范围是:[0, n),即,下标最大取值为n-1

数组下标在引用数组元素时,可以是非常灵活的使用方法:可以是常量,也可以是变量或者由变量组成的表达式!

 

特别注意:

若定义:

int  ar[5];

那么,在数组元素引用语句中,ar[5]只代表“下标为5的第6个元素”

数组的内存映像图:

                                    

 

用上述方法,可以将int  ar[5];在内存中的情况表示如下:

                                      

 

ar中的5个元素分别如图是a[0]到a[4];在存储结构(物理)角度讲,ar[0]的前面存在着4B空间(而且有很多很多);ar[4]的后面存在着4B空间(而且有很多很多);即,ar[5],ar数组的下标为5的第6个元素,在物理角度是存在的!但是在逻辑角度是不存在的!

而且,所谓“下标越界”的“错误”,在C语言编译软件中,是无法发现的!

 

数组下标越界这种错误是C编译软件所无法察觉的,而它又是致命错误;这意味着“下标越界”的错误,只能C语言程序员自己避免和发现!

 

若定义一个拥有5个元素的数组ar,那么,在逻辑上ar[5]是不存在的;但是,在物理(内存存储空间)上,ar[5]是存在的!

数组元素引用过程中,ar[5]不代表ar数组(的所有元素或任意一个元素),而是表示下标为5的第六个元素,属于下标越界错误!

 

3、数组元素赋初值

赋初值”操作仅存在定义语句中!

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

(2)int  a[5] = {1, 2, 3, 4, 5, 6}; // 初值个数多于所申请的元素个数,非法!

(3)int  a[5] = {1, 2, 3}; <=>   int  a[5] = {1, 2, 3,};  加不加逗号是一样的

    不完全赋初值方案:初值个数少于数组定义时所申请的元素个数,这种情况被称为:不完全赋初值;

    不完全赋初值,将对数组从下标为0的第一个元素的连续若干个元素赋初值,而未赋初值的其它元素的值,是0!

(4)int  a[] = {1, 2, 3, 4, 5, 6, 7,};

    上述情况是:定义数组时,不明确声明数组元素个数,但赋初值,则,数组元素个数取决于初值个数!

定义数组时不明确声明数组元素个数,但是又不赋初值,则,这是语法错误!

 

引入一个重要话题:对于数组定义的深度理解

int  a[5]; 这种定义可以看做:int[5]  a;

关于变量定义的基本语法是:

type 变量名称;

此时type就是int[5];变量名称就是a;说明a是一个类型为int[5]的空间。

int[5]成为一种数据类型。

对比:int  a[];可以看做:int[]  a;

对于表示类型的int[],不能满足数据类型的两个要素!

 

​​​​​​​4、使用数组处理数据特点

用数组存储数据时,应遵循如下3个基本原则:

1、从下标为0的第一个元素空间开始存放

2连续存放数据;

3、上述两个原则必须动态成立!

关于第三点是说:如果在处理存储于数组中数据,存在“增加”“删除”数据等操作,必须在这些操作结束时,依然满足上述两个原则。

为什么?

数组元素的遍历:

将存储于数组中的数据,无缺失、无重复的访问一遍,称为“遍历”。

假设一个拥有n个元素的数组中,存放着m个数据,且m <= n的;若按照上述三原则存储这些数据,则,可以用如下方法遍历这个数组:

for(i = 0; i < m; i++)

…a[i]…

 

5、一维数组例题

要求编程实现:录入学生成绩,并对成绩进行插入、删除、查找、排序、求平均分数等操作。

二、二维数组

​​​​​​​1、二维数组

int m[3][4];

上述语句定义了一个3行4列的二维数组。

二维数组的定义与一维数组一样,应该遵循相同的原则。

二维数组m共有12个元素,每个元素都是int类型的。

这12个元素的下标分别是:

m[0][0]、m[0][1]、m[0][2]、m[0][3]、

m[1][0]、m[1][1]、m[1][2]、m[1][3]、

m[2][0]、m[2][1]、m[2][2]、m[2][3]、

 

2、二维数组的内存映像图

二维数组在内存中是一维存放的:

                             

C语言中,二维数组中元素排列的顺序是按行存放的,即在内存中先顺序存放第一行的元素,再存放第二行的元素。

​​​​​​​3、二维数组赋初值

与一维数组赋初值一样,二维数组赋初值只能在定义语句中进行

二维数组赋初值与一维数组赋初值遵循相同的原则:

(1)int a[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};     // 逻辑角度

(2)int a[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};             // 物理(存储)角度

(3)int a[3][4] = {{1, 2, 3, 4, 5}, {6, 7, 8}, {9, 10, 11, 12}};     //错误

(4)int a[3][4] = {{1}, {5}, {9}};                                              //部分元素赋初值

    int a[3][4] = {{1}, {0, 6}, {0, 0, 11}};

(5)int a[3][] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};    //上述写法是错误的!

    int a[][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};    //正确的

 

    分析如下:

    int a[3][4]; => int[4] a[3]; 假设type为int[4],则,左式可以看做:

    type a[3]; 说明:a是一个一维数组,每一个元素的类型是type,即,int[4]类型,即,由4个int元素组成的一个一维数组!

    int a[][4] = {…}; => int[4] a[] = {…}; 由于int[4]明确的说明,应该将初值中的数据,每4个划为一组(一维数组);这使得C编译软件有明确的指示,可以无二义性的操作。

    int a[3][] = {…}; => int[] a[3] = {…}; 由于int[]没有说明长度,即,数据类型长度不确定,不能构成正确的,有效的数据类型,因此,是语法错误!

 

同理:

int a[3][4][5]; 正确

int a[][4][5] = {…}; 正确 int[4][5] a[] = {…}

int a[3][][5] = {…}; 错误 int[][5] 长度不定!

int a[3][4][] = {…}; 错误 int[4][] 长度不定!

int a[3][][]… 同样是错误的

4、二维数组的输出

 

void showTwoDimensionArrayValue(int (*m)[4], int rowCount, int colCount){
    int i;
    int j;

    printf("二维数组的值为:");

    for(i = 0; i < rowCount; i++){
        for(j = 0; j < colCount; j++){
            printf("%2d ", m[i][j]);
        }
    }
    printf("\n");
}


void main(void){

    int m[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};  


    showTwoDimensionArrayValue(m, 3, 4);

}
 

 

void showMatrix(int *matrix, int rowCount, int colCount){
    int i;
    int j;

    for(i = 0; i < rowCount; i++){
        for(j = 0; j < colCount; j++){
            printf("%d ", matrix[i * colCount + j]);
        }
        printf("\n");
    }
}

 

void main(void){

    int m[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};  


    showMatrix(&m[0][0], 3, 4);  //无任何警告
    //showMatrix(m1, 3, 4);       //能输出,但有警告,说类型不同
}   

//仍需后续多实践检验找出原因

 

三、字符数组与字符串

用来存放字符数据的数组是字符数组。字符数组中的一个元素存放一个字符。

字符串:是以0结束的字符数组。

1、字符数组的定义

   int a[10]; 整型数组,即,数组的每个元素类型都是int类型的。

   char a[10]; 字符数组,即,数组的每个元素类型都是char类型的。

2、字符数组初始化

如果在定义字符数组时不进行初始化,则数组中各元素的值是不可预测的,是垃圾数据。

方法1:逐个字符赋值给数组中各元素

(1)char c[10] = {'I', '', 'a', 'm', '', 'h', 'a', 'p', 'p', 'y'};   //数组长度为10

(2)char c[10] = {'c', '', 'p', 'r', 'o', 'g', 'r', 'a', 'm'};

   初值个数(9)小于数组长度(10),则只将这些字符赋值给数组中前面那些元素,其余的元素自动定为空字符(即'\0')

(3)char c[10] = {'I', '', 'a', 'm', '','s', 'o', '', 'h', 'a', 'p', 'p', 'y'};   //错误的

(4)char c[ ] = {'I', '', 'a', 'm', '', 'h', 'a', 'p', 'p', 'y'};  //不指定数组长度,根据后面的元素确定数组长度

方法2:用字符串常量使字符数组初始化

(1)char c[10] = {"I am happy"};

     char c[10] = "I am happy";     

     char c[10] = {'I', '', 'a', 'm', '', 'h', 'a', 'p', 'p', 'y', '\0'};

     上面三个式子是等价的。上面两个字符数组的数组长度为11,而不是10.因为字符串常量的最后由系统加上一个'\0'.

3、字符数组的引用

通过c[i]引用字符数组中的一个元素,得到一个字符。

4、字符串和字符串结束标志

'\0'代表ASCII码为0的字符,从ASCII码表中可以查到,ASCII码为0的字符不是一个可以显示的字符,而是一个“空操作符”,即它什么也不做。用它作为字符串结束标志不会产生附加的操作或增加有效字符,只起一个供辨别的标志。

 

对于一个字符串,在遇到字符'\0'时,表示字符串结束,由它前面的字符组成字符串。

如果前面9个字符都不是空字符,第10个字符是空字符,则此字符串的有效字符为9个;若用字符数组存储此字符串,则数组长度为10.

 

关于“以0结束”的问题:

char s[4] = {‘A’, ‘B’, ‘C’, ‘0’};   是字符数组,不是字符串

char s[5] = {‘A’, ‘B’, ‘C’, ‘0’, 0}; 既是字符数组,也是字符串

char s[5] = {‘A’, ‘B’, ‘C’, ‘0’}; 既是字符数组,也是字符串

char s[5] = ”ABC0”;   <=>  char s[5] = {‘A’, ‘B’, ‘C’, ‘0’};   <=>  char s[5] = {‘A’, ‘B’, ‘C’, ‘0’, 0};

char s[] = “ABCDEFG”;    printf(“%d\n”, sizeof(s));   

屏幕输出结果为8,表明s数组的元素个数确实是8个,也就表明了”ABCDEFG”的最后确实存在着一个看不见的0!

 

C语言对于字符串的处理遵循一个基本原则:

遇0则止!

C语言的库函数、我们所编写的程序,对于字符串的处理,都需要遵循这个原则!

这个原则同时要求提供C语言库函数的、C语言编译软件的制造者们和程序员,对于字符串的处理,都需要“以0为止”!即,在构造字符串时,必须在字符串的最后,存在(写上)0结束标志。

 

5、字符串与字符数组的关系

在C语言中没有专门的字符串变量,如果想将一个字符串存放在变量中以便保存,必须使用字符数组,即用一个字符型数组来存放一个字符串,数组中每一个元素存放一个字符。例如“char a[10]="love".

字符串常量定义:用双引号(“”)括起来的0个或者多个字符组成的序列

字符串常量存储:每个字符串尾自动加一个 ‘\0’ 作为字符串结束标志

6、字符数组的输入输出

方法1:逐个字符输入输出。

void main(void){
    char c[ ] = "I am happy"; 
    int i;

    for(i =0; i < 10; i++){
        printf("%c", c[i]);
    }
    printf("\n");

}

方法2:将整个字符串一次输入或输出。

void main(void){
    char c[ ] = "I am happy"; 
    
    printf("%s", c);

}

//一维数组和二维数组的例子

#include<stdio.h>
//疑问:如何把数组名称加进去???????


void showArrayValue(int *a, int count);
void showTwoDimensionArrayValue(int (*m)[4], int rowCount, int colCount);
void showMatrix(int *matrix, int rowCount, int colCount);

void showMatrix(int *matrix, int rowCount, int colCount){
	int i;
	int j;

	for(i = 0; i < rowCount; i++){
		for(j = 0; j < colCount; j++){
			printf("%d ", matrix[i * colCount + j]);
		}
		printf("\n");
	}
}


void showTwoDimensionArrayValue(int (*m)[4], int rowCount, int colCount){
	int i;
	int j;

	printf("二维数组的值为:");

	for(i = 0; i < rowCount; i++){
		for(j = 0; j < colCount; j++){
			printf("%2d ", m[i][j]);
		}
	}
	printf("\n");
}

void showArrayValue(int *a, int count){
	int i;

	printf("数组的值为:");
	for(i = 0; i < count; i++){
		printf("%d ", a[i]);
	}
	printf("\n");
}

void main(void){
	int a1[5] = {1, 2, 3, 4, 5};  //“赋初值”操作仅存在于定义语句中!
	int a2[5] = {1, 2, 3,};
	int a3[5] = {1, 2, 3};
	//int a4[5] = {1, 2, 3, 4, 5, 6};  //错误提示:too many initializers

	int m1[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};  
	int m2[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};        
	//int m3[3][4] = {{1, 2, 3, 4, 5}, {6, 7, 8}, {9, 10, 11, 12}};  //错误提示:too many initializers
	int m4[3][4] = {{1}, {5}, {9}};
	int m5[3][4] = {{1}, {0, 6}, {0, 0, 11}};

	showArrayValue(a1, 5);
	showArrayValue(a2, 5);
	showArrayValue(a3, 5);
	printf("\n");

	showTwoDimensionArrayValue(m1, 3, 4);
	showTwoDimensionArrayValue(m2, 3, 4);
	showTwoDimensionArrayValue(m4, 3, 4);
	showTwoDimensionArrayValue(m5, 3, 4);
	printf("\n");

	showMatrix(&m1[0][0], 3, 4);  //无任何警告
	//showMatrix(m1, 3, 4);       //能输出,但有警告,说类型不同
	printf("\n");
}

猜你喜欢

转载自blog.csdn.net/weixin_42072280/article/details/83513789