C语言复习笔记(三)数组

今天我们来复习第三章 数组

第三章 数组

上一章传送门:顺序、循环、选择结构

下一章传送门 :函数

我们学过的数组只有三种:一维数组二维数组字符数组,因为一维数组和二维数组大体都一样,我就一起说了。

一维数组和二维数组

一维数组定义:
每个元素只带有一个下标的数组,定义方式:类型说明符 数组名[整型常量表达式]同样先定义后使用 比如 int a[3];定义整型数组a,含有三个元素a[0]a[1]a[2]//第一个下标为0。
数组的初始化:
第一维长度可以不写,其它维必须写

int a[]={1,2};合法,
int a[][3]={2,3,4};合法,
int a[2][]={2,3,4};非法。

没有初始化元素值为随机,如在int a[5];中,元素a[4]值为一个不确定的随机数。
//常见编译出来结果很大的错误
元素的引用:
数组元素的下标从0开始,到数组长度减1结束。所以int a[5];中数组最后一个元素是a[4]。要把数组元素看作一个整体,可以把a[4]当作一个整型变量。

一维数组的初始化

为了使程序简洁,常在定义数组的同时给各数组元素赋值,这称为数组的初始化
(1) 在定义数组时对全部数组元素赋予初值

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

将数组中各元素的初值顺序放在一对花括号内,数据间用逗号分隔。花括号内的数据就称为“初始化列表”。
(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};
or
int a[10]={0};	//未赋值的部分元素自动设定为0

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

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

但是,如果数组长度与提供初值的个数不相同,则方括号中的数组长度不能省略

引用一维数组

例 对10个数组元素依次赋值为0,1,2,3,4,5,6,7,8,9,要求按逆序输出。

#include<stdio.h>
int main()
{
	int i,a[10];
	for(i=0; i<=9;i++)	//对数组元素a[0]~a[9]赋值
		a[i]=i;
	for(i=9;i>=0;i--)	//输出a[9]~a[0]共10个数组元素
		printf("%d ",a[i]);
	printf("\n");
	return 0;
}

解析:
C语言复习笔记(三)数组_第1张图片
C语言复习笔记(三)数组_第2张图片

下面是二维数组

二维数组的定义

二维数组定义的一般形式为:

类型说明符 数组名[ 常量表达式][ 常量表达式];
例如:
int a[3][4];

表示定义了一个 3×4,即 3 行 4 列总共有 12 个元素的数组 a。这 12 个元素的名字依次是:a[0][0]、a[0][1]、a[0][2]、a[0][3];a[1][0]、a[1][1]、a[1][2]、a[1][3];a[2][0]、a[2][1]、a[2][2]、a[2][3]。

与一维数组一样,行序号和列序号的下标都是从 0 开始的。元素 a[i][j] 表示第 i+1 行、第 j+1 列的元素。数组 int a[m][n] 最大范围处的元素是 a[m–1][n–1]。所以在引用数组元素时应该注意,下标值应在定义的数组大小的范围内。

此外,与一维数组一样,定义数组时用到的“数组名[常量表达式][常量表达式]”和引用数组元素时用到的“数组名[下标][下标]”是有区别的。前者是定义一个数组,以及该数组的维数和各维的大小。而后者仅仅是元素的下标,像坐标一样,对应一个具体的元素。

二维数组的初始化

可以用下面的方法对二维数组进行初始化。
(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};

效果与第 1 种是一样的。但第1种方法更好,一行对一行,界限清楚。第 2 种方法如果数据多,写成一大片,容易遗漏,也不易检查。
(3) 也可以只对部分元素赋初值。比如:

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

它的作用是对第一行的前两个元素赋值、第二行和第三行的第一个元素赋值。其余元素自动为 0。初始化后数组各元素为:
在这里插入图片描述
(4)如果在定义数组时就对全部元素赋初值,即完全初始化,则第一维的长度可以不指定但第二维的长度不能省。比如:

int a[3][4] = {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};

系统会根据数据总数和第二维的长度算出第一维的长度。但这种省略的写法几乎不用,因为可读性差。
(5) int a[3][4]={0};
二维数组“清零”,里面每一个元素都是零

二维数组的输出

二维数组有行和列,那么如何输出里面的元素呢?在讲述一维数组的时候说过,“数组的元素只能一个一个输出”,二维数组也不例外。在一维数组中是用一个 for 循环进行输出,而二维数组元素的输出要使用两个 for 循环嵌套

#include <stdio.h>
int main(void)
{
    int a[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
    int i;  //行循环变量
    int j;  //列循环变量
    for (i=0; i<3; ++i)
    {
        for (j=0; j<4; ++j)
        {
            printf("%-2d\x20", a[i][j]);
        }
        printf("\n");
    }
    return 0;
}
//提示:“printf("%-2d\x20",a[i][j]);”中的“%-2d”,其中“-”表示左对齐,如果不写“-”则默认表示右对齐;“2”表示这个元素输出时占两个空格的空间,所以连同后面的 \x20 则每个元素输出时都占三个空格的空间。

C语言复习笔记(三)数组_第3张图片
下面就是字符数组

字符数组

字符数组(string)
字符数组就是数组中的每个元素都是字符。定义方法同普通数组的定义相同 ,即逐个对数组元素赋值 初始化:char a[5]={‘g’,’o’,’o’,’d’};其中a[4]=‘\0’
为了测定字符串的实际长度,C语言规定了一个“字符串结束标志”,以字符′\0′作为结束标志
例 ″C program″ 字符串是存放在一维数组中的,占10个字节,字符占9个字节,最后一个字节′\0′是由系统自动加上的。
注:
char str[];str=“Thank you.”;这种字符数组的整体赋值说错误的,字符数组只能一一赋值
而数组元素的整体赋值只能在初始化时使用。比如char str[]={“Thank you.”}
①用%c格式将字符逐个输入输出
②用%s格式将整个字符串一次输出输入

scanf函数中的输入项如果是字符数组名,不要再加地址符&,因为在C语言中数组名代表该数组第一个元素的地址(或者说数组的起始地址)。

字符数组的初始化

对字符数组初始化,最容易理解的方式是用“初始化列表”,把各个字符依次赋给数组中各元素。

char c[10]={I,′ ′ ,′a′,′m′,′ ′,′h′,′a′,′p′,′p′,′y′};		//把10个字符依次赋给c[0]~c[9]这10个元素

如果在定义字符数组时不进行初始化,则数组中各元素的值是不可预料的。
如果大括号中提供的初值个数(即字符个数)大于数组长度,则出现语法错误。
如果初值个数小于数组长度,则只将这些字符赋给数组中前面那些元素,其余的元素自动定为空字符(即′\0′)。

char c[10]={′c′,′ ′,′p′,′r′,′o′,′g′,′r′,′a′,′m′};

在这里插入图片描述
如果提供的初值个数与预定的数组长度相同,在定义时可以省略数组长度,系统会自动根据初值个数确定数组长度。

char c[]={I,′ ′,′a′,′m′,′ ′,′h′,′a′,′p′,′p′,′y′};		//数组c的长度自动定为10

也可以定义和初始化一个二维字符数组。

char diamond[5][5]={{′ ′,′ ′,*},{′ ′,*,′ ′,*},{*,′ ′,′ ′,′ ′,*},{′ ′,*,′ ′,*},{′ ′,′ ′,*}};

C语言复习笔记(三)数组_第4张图片

字符数组的输入输出

注意以下三种形式
形式一:

	char c[6];
	scanf("%s",c);

从键盘输入:
China↙
系统会自动在China后面加一个′\0′结束符。
形式二

	char str1[5],str2[5],str3[5];
	scanf("%s%s%s",str1,str2,str3);

如果利用一个scanf函数输入多个字符串,则应在输入时以空格分隔
从键盘输入:
How are you? ↙
由于有空格字符分隔,作为3个字符串输入
如图:
在这里插入图片描述
形式三

	char str[13];
	scanf("%s",str);

从键盘输入:
How are you? ↙
由于系统把空格字符作为输入的字符串之间的分隔符,因此只将空格前的字符″How″送到str中
如图:
在这里插入图片描述

下边我们再来简单介绍几个特殊字符串处理函数

(1)gets(字符数组)
调用形式为gets(字符数组不加中括号) 从终端输入一个字符串到字符数组中,并且得到一个函数值。
(2)puts(字符数组)
调用形式同gets(),将一个字符串(以‘\0’输出终端)

#include <stdio.h>
int main()
{
	char str[]={"China\nBeijing"};
	puts(str);
	return 0;
}

C语言复习笔记(三)数组_第5张图片
(3)strlen(字符数组)
统计字符串长度,此函数计算出字符数组为起始地址的字符串的长度(实际长度不包括‘\0’),并作为函数值返回。

#include <stdio.h>
#include <string.h>
int main()
{
	char str[10]="China";
	printf("%d,%d\n",strlen(str),strlen("China"));	
}

C语言复习笔记(三)数组_第6张图片
(4)strcat(字符数组)
字符串连接函数。调用形式为strcat(字数1,字数2) 该函数将字符数组2所指字符串内容连接到字符数组1所指的字符串后面,并自动覆盖字符数组串1末尾的‘\0’
注意:字符数组1必须足够大,以便容纳连接后的新字符串

char str1[30]={"People′s Republic of "};
char str2[]={"China"};
printf("%s", strcat(str1, str2));

如图:
C语言复习笔记(三)数组_第7张图片
(5)strcmp(字符数组)
字符串比较函数。调用形式strcmp(字符数组1,字数2) 该函数按照ASCII码顺序比较字符数组1和数组2所指字符串的大小。若字符数组1>字符数组2,函数值大于0;=,0;<,小于0。
具体用法:从第一个字符开始比较ASCII,与长度无关,从左往右,即ac

strcmp(str1, str2);
strcmp("China", "Korea");
strcmp(str1, "Beijing");

(6)strcpy(字符数组)
作用:将字符串2复制到字符数组1中去。
字符数组1必须定义得足够大,以便容纳被复制的字符串2。字符数组1的长度不应小于字符串2的长度。
“字符数组1”必须写成数组名形式,“字符串2”可以是字符数组名,也可以是一个字符串常量。
若在复制前未对字符数组1初始化或赋值,则其各字节中的内容无法预知,复制时将字符串2和其后的′\0′一起复制到字符数组1中,取代字符数组1中前面的字符,未被取代的字符保持原有内容。
不能用赋值语句将一个字符串常量或字符数组直接给一个字符数组。字符数组名是一个地址常量,它不能改变值,正如数值型数组名不能被赋值一样。
拓:可以用strncpy函数将字符串2中前面n个字符复制到字符数组1中去。
将str2中最前面2个字符复制到str1中,取代str1中原有的最前面2个字符。但复制的字符个数n不应多于str1中原有的字符(不包括′\0′)。

char str1[10], str2[]="China";
strcpy(str1, str2);strcpy(str1, "China");

执行后:
在这里插入图片描述
最后就是转换大小写的函数了
(7)strlwr(字符串)
作用:将字符串中大写字母换成小写字母。
(8)strupr(字符串)
作用:将字符串中小写字母换成大写字母。

注意

以上介绍了常用的8种字符串处理函数,它们属于库函数。库函数并非C语言本身的组成部分,而是C语言编译系统为方便用户使用而提供的公共函数。不同的编译系统提供的函数数量和函数名、函数功能都不尽相同,使用时要小心,必要时查一下库函数手册。
在使用字符串处理函数时,应当在程序文件的开头用#include 把string.h文件包含到本文件中。

ok,今天的着实有点多,一起加油吧,坚持就是胜利,奥利给!

你可能感兴趣的:(笔记)