第五章、数组

int main()
{
//int, char, float, double
//构造类型: 基本的类型(int,char,float,double)进行写法上的变换所生成的类型。

5.1 一维数组:

定义:

类型说明 数组名**[常量表达式]**
int a[10];

注意点
a)数组名就是变量名。 比如: a

b) 注意格式只能是方括号,而不能是圆括号。

c)数组名后边是方括号括起来的常量表达式(数字), 2 * 5也行,int a[2 * 5]

d)一维数组就是有一对中括号 [ ]

e)a[10]中的这个数字10 表示该一维数组a中有10个元素。(相当于你定义了10个变量,每个变量都是整形。 但是,这10个元素分别是 a[0] — a [9] , 绝对不包括a[10] 。

例如:

int a[100] , 这100个元素分别是 a[0] — a[99] , 绝对不包括 a[100] ,

f)数组定义格式必须严格。

例如:

int a[10];
a[1] = 10;
a[2] = 14;
a[10] = 30;  // 这个a[10]是错误的,因为数组存储时候在内存空间中是连续存储的,假如
						 // a[10]将其他变量的地址给顶掉了,会导致程序出问题。严重点导致程序完蛋.
						 // 不定时崩溃

实验:验证以下程序中 没有 a[10] ,

请添加图片描述

g)常量表达式中,可以是常量,但不能包含变量**,也就是说,c语言中不允许对数组大小做动态改变。

例如:

int i;
i = 9;
int a[9];  //不可以是变量,只能是常量

h)int a[1000] ; 相当于定义了1000个整型变量, a[0] — a[9999] ;

数组的引用: c语言规定,只能引用数组中的元素,不能引用整个数组。

int a[10];
a[0]

数组元素的表现形式为:

数组名[下标] 下标一般都是整形常量。

int a[10];   //不能忘记这个方括号 
// 下标就是 0-9
a[0] = 10;
a[1] = 10;
a[0] = a[5] + a[6] - a[2*2];  //千万不要引用a[10], 能引用的就是a[0]-a[9].
int i, a[10];
for(i=0;i<=9;i++)   // i = 0-9
	a[i] = i;

for(i=9;i>=0;i--)   // i = 9-0
	printf("a[%d]=%d\n",i,a[i]);

5.1.1 数组的初始化:

(1)只定义,没有初始化,所以里边是不确定的值

int a[10];  //只是定义,没有初始化其中都是不确定的值

请添加图片描述

(2)定义时赋初值

初始化的值太多,则编译就会报错。

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

请添加图片描述

只给一部分数组元素赋值,其他的数组元素系统就会自动给0.

int a[10] = {1,34,6,6,7,8,};

如果要对全部数组元素赋初值,那么可以不指定数组长度。

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

请添加图片描述

若被定义的数组长度与提供初值的个数不想同时,数组长度不能省略

5.2 二维数组

5.2.1 二维数组形式:

int a[10];  //下标为 0-9
float b[8];  // 下标为 0-7

二维数组为 [ ] [ ]

二维数组的一般形式:

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

数组名[下标][下标];

eg: 

float a[3][4];  //二维数组的形式;

//1. 这里如何理解 a[3][4]呢--> a 是一个3行4列的数组;

int b[6][5];   /// 6行5列的一个组

// 2. 可以理解为特殊的一维数组, 能够引用的b[6]的下标是 0-5 , b[5]有5个元素,b[1]有5个
//  元素,b[2]有5个元素。
/** b[0][0], b[0][1], b[0][2], b[0][3], b[0][4]
		b[1][0], b[1][1], b[1][2], b[1][3], b[1][4]
		b[2][0], b[2][1], b[2][2], b[2][3], b[2][4]
		b[3][0], b[3][1], b[3][2], b[3][3], b[3][4]
		b[4][0], b[4][1], b[4][2], b[4][3], b[4][4]
		b[5][0], b[5][1], b[5][2], b[5][3], b[6][4]

5.2.2 多维数组 [ ] [ ] [ ] …

可以理解为该数组有a页,每一页都有一个b行c列的二维数组

float a[2][3][4]; // 三维数组(多维数组),在内存中排列顺序: **第一维下标变化最慢,
									// 最右边的下标变化最快。

实际存储的是:
a[2] --> 0-1
a[3] --> 0-2
a[4] --> 0-3

a[2][3][4] -->
a[0][0][0], a[0][0][1], a[0][0][2], a[0][0][3]
a[0][1][0], a[0][1][1], a[0][1][2], a[0][1][3]
a[0][2][0], a[0][2][1], a[0][2][2], a[0][2][3]
a[1][0][0], a[1][0][1], a[1][0][2], a[1][0][3]
a[1][1][0], a[1][1][1], a[1][1][2], a[1][1][3]
a[1][2][0], a[1][2][1], a[1][2][2], a[1][2][3]**

数组中的错误写法:

诸如此类都是错误
a[5-4][3>1], 
a[0,1]
a[0][1]

数组中赋值:

a[0][1] = a[2][3]  
=
a[0] =  a[1]

eg:
int a[5];  // 0-4
int b[3][4]; // 第一维0-2 , 第二维0-3
b[3][0] = 2; //这是错误的,3是没有被定义过的
b[0][4] = 2; //这个4也是不能被拿来用的

int a[3][4];
int i,j;
for(i=0; i<3;i++) //0,1,2 --> i
{
	for(j=0;j<4;j++) // 0,1,2,3 --> j
		{
				a[i][j] = i * j;
		}
}
for(i=0;i<3;i++)
{
	for(j=0;j<4;j++)
		{
			printf("a[%d][%d]=%d\n",i,j,a[i][j]);
		}
}

请添加图片描述

5.2.3 二维数组的初始化:

a)分行给二维数组赋初值

int a[3][4] = { {1,2,3,4},{ 2,4,6,8},{5,6,7,8} }; 
 //这个就是三行四列的另一种方式。 不常用。
b) 将所有数据放在一个大括号里:
int b[3][4] = { 1,2,3,4 5,6,7,8 2,4,5,6};
特点: 每个字段之间使用空格 来进行区分

c.0) 对部分元素赋初值
int c[3][4] = { {1},{3,4} };  //定义是三行四列,但是赋初值的只有第一行第0列和
															// 和第二行第0列以及第1列。

int d[3][4] = { {1},{}, {9} }; //变量是三行四列,但是赋的值只有3行0列。

int a[3][4] -> 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]
							
c.1) 对部分元素赋初值:
int a[][4] = { {0,0,3}, {}, {0,10} };  // 三行四列
d) 对全部元素赋初值: (可以不指定第一维的长度,第二维长度不能省略。)

int b[][4] = { {1,2,3,4}, {2,3,4,5}, {3,4,5,6}, {5,6,7,8} }

//16/4 =4 ; 所以第一维的数据是4,具体是多少要看有多少行。**
e)对部分元素赋初值: (可以不指定第一维长度,但是第二维长度不能省略)
int a[][4] = { {0,3,2},{0},{0} };  //三个括号表示3行,**

5.3 ※字符数组

(1)字符数组的定义

(2)字符数组的初始化

(3)二维数组的引用

(4)字符串和字符串结束标记

(5)字符数组的输入输出

(6)字符串处理函数

复习:

int a[10]; int b[4][5];

5.3.1 字符数组 :

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

一维数组:

eg:

char c[10]; // 0-9
c[0] = 'I';
c[1] = ' ';
c[2] = 'a';
c[3] = 'm';
c[4] = 'h';
c[5] = 'a';
c[6] = 'p';
c[7] = 'p';
c[8] = 'y';
c[9] = '!';

请添加图片描述

字符数组的初始化:

a) 逐个字符付给数组中的元素。
char a[10] = { ‘i’,’ ‘,‘a’,‘m’,’ ',‘h’,‘a’,‘p’,‘p’,‘y’};

b) 如果提供的初值个数和预定的数组长度相同,定义时可以省略数组长度,系统或自动根据初值个数确定数组长度。
char [ ] = { ‘i’,’ ‘,‘a’,‘m’,’ ',‘h’,‘a’,‘p’,‘p’,‘y’ } ; // 0-9

c) 数组长度 < 初值个数
char c[9] = { ‘i’,’ ‘,‘a’,‘m’,’ ',‘h’,‘a’,‘p’,‘p’,‘y’ } ;
//是10个初值,但是定义数组长度是9,所以程序会出问题

d) 数组长度 > 初值个数
char d[12] = { ‘i’,’ ‘,‘a’,‘m’,’ ',‘h’,‘a’,‘p’,‘p’,‘y’};
//是10个初值,但是定义数组得长度为12,则将这些字符赋值给数组中前面的那些元素,其余得元素值可能会给\0 , 也可能无法发确定,所以不建议这样作。

请添加图片描述

上述初始化相当于:

d[10] = 0; // 0 == ‘\000’

d[11] = 0;

二维数组:

char dia[3][3] = { { ' ', '*', ' '  }, { '*' , ','  , '*', },{' ', '*', ' '   } };

int i,j
for(i=0; i<=2;i++)
{
	for(j=0;j<3;j++)
	{
		printf("%c",dia[i][j]);
	}
printf("\n");
}

一维数组:

char c[10] =  { 'i',' ','a','m',' ','h','a','p','p','y'};
int i;
for(i=0;i<10;i++)
{
	printf("%c",c[i]);
} 
printf("\n");

输出结果是: i am happy

5.3.2 字符串和字符串结束标记

补充一个初始化字符数组的方法:

用字符串来初始化字符数组

eg:

char d[ ]  = { "I am happy" } ;  

**//系统会自动在字符串末尾增加一个 \0 , 叫做字符串结束标记。
// 字符串结束标记,用来标记一个字符串的结束
// 为了测定一个字符串的实际长度,c语言规定了一个字符串结束标记,就是这个\0.
// 如果一个字符出啊,他的第10个字符为'\0' , 则此字符串的有效字符为9个。
// 也就是说,在遇到字符'\0'的时候,表示字符串结束。由'\0'前边的字符组成字符串。
//这个“i am happy" 有10个有效字符,但是他在内存中占11个字节,因为最后一个字节放的是'\0'**

char *p = "i am happy",

char c[11] = "I am happy" ;   
//这个才是对的,因为字符串类型的话后面自动有一个\0,是用来标记字符串结束的。
//所以是11个字符才合适.

请添加图片描述

数组中 字符与字符串的区别

char c[ ] =  { 'I',' ','a','m',' ','h','a','p','p','y'};
char d[ ] = {"I am happy"};  

====>

char c[ ] =  { 'i',' ','a','m',' ','h','a','p','p','y',**'\0'**}; //这种方式不用
//这两者是等价的
//注意: 字符串结束标记并不会显示出来。
char d[ ] = {"I am happy"}; //只要用字符串常量,系统就会自动给字符串末尾增加一个\0.

5.3.3 字符数组的输入输出

eg:

char c[] = "china";
printf("%s\n",c); // %输出一个字符串

注意:

a) 字符串中printf输出的字符不包括\0

b) %s 对应的是字符数组名,

char c[] = "china";
printf("%s\n",c);

c) %c 就是可以输出一个字符 print(“%c\n”,c[0]);

char c[] = "china";
printf("%c\n",c[0]);

d) 即便数组长度大于字符串数组长度,也只输出到\0 结束。

eg:

char c[20] = "china";
printf("%s\n",c);

e)如果一个字符数组中包含多个\0,printf也只是遇到第一个\0时就停止输出.

char c[20] = "china";
printf("%s\n,c);       //结果为: china
char c[2] = '\0';
printf("%c\n",c);      // 结果为: ch  
// \0为字符串的结束标志。

从键盘输入一个字符串,用 scanf 来完成

char c[100];
scanf("%s",c); //从键盘输入一个字符串。 c是字符数组名。
printf("%s\n",c); //
char s1[10],s2[10],s3[10];
scanf("%s%s%s",s1,s2,s3); 
// 输入how are you 之后,s1为how,s2为are,s3为you。
所以:scanf函数通过空格来分割。

区别:
char s1[100];
scanf("%s",s1); //输入一个字符串的时候不能加入空格,否则空格后的内容会被丢弃
printf("%d\n",s1);  //使用%d来打印数组的起始地址
printf("%d\n",&s1);  **(数组中的s1)和 &s1被等同看待,都被认为是数组的起始地址。**

scanf("%s",s1);  ==> scanf("%s",&s1);
//**以上情况只能用在数组中。**

注意: 此处s1本身代表的就是这个数组的起始地址。加上也可以

eg:

int a;
scanf("%d",&a);  //  &  地址符号. 地址: 0x开头的就是地
printf("%d\n",&a);  // 此处打印出来的是a的地址。
printf("%d\n",a);   // 此处打印出来的是a的值。

而此处因为是int型,必须使用&来取地址。

//在c语言中,一维字符数组可以看成字符串变量。里边存的就是字符串变量。

5.4 字符串处理函数

1. puts(字符串数组)

// 将一个字符串输出到屏幕(自动换行),只能输出一个字符串。

char s[100]  = "are you ok?";
puts(s); // ->  printf("%s\n",str);  等价

2. gets(字符数组名)

// 从键盘输入一个字符串到字符数组中,只能输入一个字符串。

char s[100];
gets(s);
printf("%s\n",s);  // 

3. stract(字符数组1,字符数组2)

// 常用的

//连接两个字符数组中的字符串,把字符串2连接到字符串1后边,结果放在字符数组1中。

注意:

a) 字符数组1必须要足够大,要能让1容纳连接后的新的字符串。

b) 连接之前两个字符串后面都有一个\0 , 连接时将字符串1后边的\0取消。连接后只在新串最后保留\0。

#include <stdio.h>
#include <string.h>
int main() {
char s1[10] ="one";
char s2[20] ="two";
strcat(s1,s2);

printf("off");
	return 0;
}

图解:

请添加图片描述

4. strcpy(字符数组1,字符串2

// 常用函数

//将字符串2拷贝到字符数组1中去。字符数组1中的内容将被完全覆盖。(可以理解为全部被字符串2取代,主要是因为拷贝时将\0也拷贝了)

字符数组1的大小一定比字符串2要大。

a) 字符数组1必须足够大,以便能够容纳下被拷贝的字符串,也就是说字符数组1的长度不能小于字符串2的长度。

b) 字符数组1必须是个数组名,通过这个数组名的内存地址才能拷贝字符串2. 字符串2也可以是数组名,也可以是个字符串常量。

c) 拷贝的时候是连同字符串后面的\0一起拷贝到字符数组中去了。

#include <stdio.h>
#include <string.h>
int main() {
char s1[15] = "this is ";
char s2[10] = "a test";
strcpy(s1,s2); //s1的大小,一定要大于s2.

	return 0;
}
#include <stdil.h>
#include <string.h>
int main() {
char s1[10] = "this is";
strcpy(s1,"a test");

	return 0;
}

d) 不能用赋值语句将一个字符串常量或者字符数组直接赋给一个字符数组。

由于不能这样干才出来了个strcpy( ) 函数.

s1 = "china"  ;  这是错的
s1 = s2 ;      错的

赋值语句只能将一个字符赋值给一个字符型变量或者数组元素。

请添加图片描述

此处a[5]这个变量是不能赋值的。

5. strcmp(字符串1,字符串2)

//比较是否相等

//比较1和2,(通过字符的ascii码进行比较)

a) 1 == 2 ,函数返回0;

1 > 2 , 返或一个正整数.

1 < 2 , 返回一个负整数 .

比较规则:

对两个字符串从左到右逐个字符比较(按ascii码值大小比较),一直到出现不同的字符或者遇到\0为止。

全部字符都相等返回0;

若出现不同的字符,则以第一个不相同的字符比较结果为准。

常用于比较相等或者不想等,一般 不用于比较大小。

a = "abcd";
b = "abkf";
解析:
a=a,b=b, c<k,所以返回负整数。

eg:

int i;
char s[10] = "one1234";
char s1[10] = "opq";
i = strcmp(s,s1);
printf("%d\n",i);   // o == o , n > p    -> 正整数表示n大。

if(s ==  s1) { }    //这个是比较地址,而不是比较内容,
使用if比较内容:
if(strcmp(s,s1)==0){} //这才是比较内容。

6. strlen(字符数组)

//测试字符串长度的函数,函数的值是字符串的实际长度,但不包括\0. 返回地单位是字节。

而存储的是中文的话,那么一个中文是占用两个字节的。

char s[10] = "open the door";
char s1[15] = "when way where";
int len = strlen(s);
int len1 = strlen(s1);
printf("%d",len);

strlen( ) 与 sizeof( ) 区别。

strlen( ) 是对于其中的内容来说的。

sizeof( ) 是查看这个 变量或者类型名 占用的内存字节数,跟里面内容无关。

如: sizeof(a) sizeof(int)

请添加图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杨优秀&

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值