C语言第四篇数组

数组

1. 数组的概念

数组是一组具有相同数据类型的数据的有序集合。

  • 数组中存放的是1个或者多个数据,但是数组元素个数不能为0。
  • 数组中存放的多个数据,类型是相同的。

2. ⼀维数组的创建和初始化

2.1 数组创建

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

  • 类型(可以是char、short、int、float)
  • 数组名定名规则和变量名相同,遵循标识符定名规则。
  • 在定义数组时,需要指定数组中元素的个数,方括弧中的常量表达式用来表示元素的个数,即数组长度。
    指定a[10]是a[0]~a[9],请持别注意,不存在数组元素a[10]。
  • 常量表达式中可以包括常量和符号常量,但不能包含变量。
    char ch[8];
    double score[10];//存储10个人分数

数组说明中其他常见的错误

  1. int k, a[k];/* 不能用变量定义数组大小*/
  2. float a[5.0] /* 数组长度不能为近似值*/
  3. float a[0]; /* 数组大小为0没有意义 */

数组元素的引用方式:
数组名[下标]
下标可以是整型常量或整型表达式。例如:
a[0]=a[5]+a[7]-a[2*3]
注意:

  • 定义数组时用到的“数组名[常量表达式]” 和引用数组元素时用到的“数组名[下标]” 是有区别的。
    • 例如∶ int a[10]; /* 定义数组长度为10 /
      t=a[6]; /
      引用a数组中序号为6的元
      素。此时6不代表数组长度 */

2.2 数组的初始化

数组的初始化⼀般使⽤大括号,将数据放在⼤括号中。

//当对数组进行初始化的时候,数组的大小可以省略。编译器会根据数组的初始化内容 ,自动计算数组的元素个数
int arr[ ] = {1,2,3,4,5};

  • //完全初始化
    • int arr[5] = {1,2,3,4,5};//5是指定数组的元素个数的
  • //不完全初始化
    • int arr2[6] = {1};//第⼀个元素初始化为1,剩余的元素默认初始化为0
  • //错误的初始化 - 初始化项太多
    • int arr3[3] = {1, 2, 3, 4};//超过3个了报错

int arr[ 10 ] = { 0 };//10个元素
int arr2[ ] ={ 0 };//这种数组只有1个元素
int arr3[ 20 ] ={ 0,1,2,3,4,5,6,7,8,9 };//20

  • 在对全部数组元素赋初值时,由于数据的个数已经确定,因此可以不指定数组长度。
    • int a[]={1,2,3,4,5};
      • 花括弧中有5个数,系统就会据此自动定义a数组的长度为5。但若数组长度与提供初值的个数不相同,则数组长度不能省略。

2.3 数组的类型

int arr1[10];//arr1数组的类型是int [10],也就是去掉名字arr1。数组的元素类型是int
int arr2[5];这个数组的类型是int [5],这个数组与上面int arr1[10];数组类型不一样
//当元素个数和元素类型发生变化后,数组的类型会发生变化

char ch[5];//ch数组的类型是char [5]

3.⼀维数组的使⽤

3.1数组下标

下标是从0开始的,假设数组有n个元素最后⼀个元素的下标是n-1
int arr[10] = {1,2,3,4,5,6,7,8,9,10};

数组12345678910
下标0123456789

数组的访问提供了⼀个操作符[ ]–下标引用操作符。
访问下标为7的元素,我们就可以使⽤ arr[7]

int arr[10] = {1,2,3,4,5,6,7,8,9,10};//这里的10是指定数组的元素个数的
printf(“%d\n”, arr[7]);//8,这里的[ ] - - 叫下标引用操作符
//这里的7是数组元素的下标
//当对数组进行初始化的时候,数组的大小可以省略。编译器会根据数组的初始化内容,自动计算数组的元素个数,比如以下
int arr2[ ] = {1,2,3,4};//就比如这里虽然没写4,编译器也会自动计算元素个数是4

3.2数组元素的打印

练习:产⽣数组所有元素的下标,那我们使⽤for循环产⽣0~9的下标就可以打印1 ~ 10

#include <stdio.h>
int main()
{
 	int arr[] = {1,2,3,4,5,6,7,8,9,10}; //初始化对应元素下标0~9,打印1~10就是打印下标0~9
 	int i = 0;
 	for(i=0; i<10; i++)//循环产⽣0~9的下标就可以打印1 ~ 10
 	{
 		printf("%d ", arr[i]);//1 2 3 4 5 6 7 8 9 10
	}
	//或者用while循环
	//while(i<10)
	//{
	//printf("%d ", arr[i]);
	//i++;
	//}
 	return 0;
}

3.3 数组的输⼊

#include <stdio.h>
int main()
{
	int arr[10] = {1,2,3,4,5,6,7,8,9,10}; 
	int i = 0;
 	for(i=0; i<10; i++)
 	{
 		scanf("%d", &arr[i]);//给数组中输入10个值
 	}
 	for(i=0; i<10; i++)
 	{
 		printf("%d ", arr[i]);//打印数组内容
 	}
 	return 0;
}

4. ⼀维数组在内存中的存储

数组在内存中是连续存放的。随着数组下标的增长,地址也是由小(低)到大(高)变化

5. sizeof计算数组元素个数

sizeof可以计算类型或者变量⼤⼩的,也可以计算数组的⼤⼩。

#include <stido.h>
int main()
{
 int arr[10] = {0};
 printf("%d\n", sizeof(arr));//40
 return 0;
}

数组中所有元素的类型都是相同的(int),那只要计算出⼀个元素所占字节的个数,数组的元素
个数就能算出来。这⾥我们选择第⼀个元素算⼤⼩就可以。

#include <stido.h>
int main()
{
 int arr[10] = {0};
 printf("%d\n", sizeof(arr[0]));//计算⼀个元素的⼤⼩,
 								//单位是字节 4
 return 0;
}
#include <stido.h>
int main()
{
 int arr[10] = {0};
 int sz = sizeof(arr)/sizeof(arr[0]);
 printf("%zd\n", sz);//数组的元素个数:10
 return 0;
}

6. ⼆维数组的创建

6.1 ⼆维数组的概念

在这里插入图片描述
一维数组是整型元素的数组
二维数组是一维数组的数组

6.2 ⼆维数组的创建

二维数组定义的一般形式为
类型说明符 数组名[常量表达式1][常量表达式2];

int arr[3][5];//3行5列。int表⽰数组的每个元素是整型类型;arr是数组名,可以根据⾃⼰的需要指定名字。

7.二维数组的引用

  • 二维数组元素的表示形式为:数组名[下标][下标]
    例如: a[2][3]
  • 下标可以是整型表达式,如 a[2-1][2*2-1]
  • 数组元素可以出现在表达式中,也可以被赋值
    例如:b[1][2]=a[2][3]/2

8. ⼆维数组的初始化

使⽤⼤括号初始化

8.1 不完全初始化

int arr1[3][5] = {1,2};
int arr2[3][5] = {0};

在这里插入图片描述

8.2 完全初始化

int arr3[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};

行\列(三行五列)01234
012345
123456
234567

8.3 按照⾏初始化

int arr4[3][5] = {{1,2},{3,4},{5,6}};
在这里插入图片描述

8.4 初始化时省略⾏,但是不能省略列

int arr5 [ ][5] = {1,2,3};
int arr6 [ ][5] = {1,2,3,4,5,6,7};
int arr7 [ ][5] = {{1,2}, {3,4}, {5,6}};
在这里插入图片描述

9. ⼆维数组的使⽤

9.1 ⼆维数组的下标

⼆维数组访问也是使⽤下标的形式,有行有列,锁定行列就可以锁定数组中的一个元素
行列都从0开始

9.2 ⼆维数组的输⼊和输出

访问整个⼆维数组,例如:⾏的选择范围是0~ 2,列的取值范围是0~4

#include <stdio.h>
int main()
{
 	int arr[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};
 	int i = 0;//遍历⾏ 
 	//输⼊ 
 	for(i=0; i<3; i++) //产⽣⾏号 0~2
	 {
 		int j = 0;
		for(j=0; j<5; j++) //产⽣列号0~5 
 		{
 			scanf("%d", &arr[i][j]); //输⼊数据 
 		}
 	 }
 //输出 
 	for(i=0; i<3; i++) //产⽣⾏号 
 	{
 		int j = 0;
 		for(j=0; j<5; j++) //产⽣列号 
 		{
 			printf("%d ", arr[i][j]); //输出数据 
 		}
 		printf("\n");
 	}
 	return 0;
}

在这里插入图片描述

10. ⼆维数组在内存中的存储

在这里插入图片描述
⼆维数组中的每个元素都是连续存放的。

11.字符数组

11.1字符数组的定义

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

11.2字符数组的初始化

  • 如果在定义字符数组时不进行初始化,则数组中各元
    素的值是不可预料的。
  • 如果花括弧中提供的初值个数(即字符个数)大于数组
    长度,则按语法错误处理。
  • 如果初值个数小于数组长度,则只将这些字符赋给数
    组中前面那些元素,其余的元素自动定为空字符
    (即′\0′)。例如:
    在这里插入图片描述
  • 如果提供的初值个数与预定的数组长度相同,在定义
    时可以省略数组长度,系统会自动根据初值个数确定
    数组长度。例如:
    在这里插入图片描述

11.3字符数组的输入输出

字符数组的输入输出可以有两种方法:

  • 逐个字符输入输出。用格式符“%c”输入或输出一个字符。
  • 将整个字符串一次输入或输出。用“%s”格式符,意思是对字符串的输入输出。
  • 说明
    • 用“%s”格式符输出字符串时,printf函数中的输出项是字符数组 名,而不是数组元素名。如:写成下面这样是不对的:printf(″%s″,c[0]);
    • 如果数组长度大于字符串实际长度,也只输出到遇′\0′结束。
    • 输出字符不包括结束符′\0′。
      如:char c[10]={″China″}; /* 字符串长度为5,连’\0’共占6个字节 */
      printf(″%s″,c);只输出字符串的有效字符“China”,而不是输出10个字符。这就是用字符串结束标志的好处。
    • 如果一个字符数组中包含一个以上′\0′,则遇第一个′\0′时输出就结束。
    • 可以用scanf函数输入一个字符串。
      例如 scanf(″%s″,c);
      scanf函数中的输入项c是已定义的字符数组名,输入的字符串应短于已定义的字符数组的长度。例如,定义 char c[6];
      从键盘输入:
      China↙系统自动在China后面加一个′\0′结束符。

12. C99中的变⻓数组

初始化数据的话,可以省略数组⼤⼩
C99中给⼀个变⻓数组,允许我们可以使⽤变量指定数组⼤⼩。

int n = a+b;
int arr[ n ];

数组 arr 就是变⻓数组,因为它的⻓度取决于变量 n 的值,编译器没法事先确定,只有运⾏时才能知道 n 是多少。
数组长度只有运行时才能确定,所以变⻓数组不能初始化。

#include <stdio.h>
int main()
{
 	int n = 0;
 	scanf("%d", &n);//根据输⼊数值确定数组的⼤⼩ 
 	int arr[n];
 	int i = 0;
 	for (i = 0; i < n; i++)
 	{
 		scanf("%d", &arr[i]);
	}
 	for (i = 0; i < n; i++)
 	{
 		printf("%d ", arr[i]);
 	}
 	return 0;
}

在这里插入图片描述

#include <stdio.h>
int main()
{
 	int n = 0;
 	scanf("%d", &n);//根据输⼊数值确定数组的⼤⼩ 
 	int arr[n];
 	int i = 0;
 	for (i = 0; i < n; i++)
 	{
 		arr[i]=6;
	}
 	for (i = 0; i < n; i++)
 	{
 		printf("%d ", arr[i]);
 	}
 	return 0;
}

输入:20
输出:6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6

12. 数组练习

练习1:多个字符从两端移动,向中间汇聚

#include <stdio.h>
int main()
{
 	char arr1[] = "welcome to bit...";
 	char arr2[] = "#################";
 	int left = 0;
 	int right = strlen(arr1)-1;
 	printf("%s\n", arr2);
 	while(left<=right)
 	{
 		arr2[left] = arr1[left];
 		arr2[right] = arr1[right];
        left++;
		right--;
		Sleep(1000);//休眠1000毫秒
		system("cls");//清理控制台屏幕的信息
 		printf("%s\n", arr2);
 	}
 	retutn 0;
}

练习2:⼆分查找(折半查找)

#include <stdio.h>
int main()
{
 	int arr[] = {1,2,3,4,5,6,7,8,9,10};
 	int left = 0;
 	int right = sizeof(arr)/sizeof(arr[0])-1;
 	int key = 0;//要找的数字 
 	int mid = 0;//记录中间元素的下标 
	while(left<=right)
 	{
 		mid = (left+right)/2;
 		if(arr[mid]>key)
 		{
 			right = mid-1;
 		}
 		else if(arr[mid] < key)
 		{
 			left = mid+1;
 		}
 		else
 		{
 			printf("找到了,下标是%d\n", mid);
 			break;
 		}
    }
 	if(left>right)
    {
 		printf("找不到\n");
    }
    return 0;
}

中间元素的下标,使⽤ mid = (left+right)/2 ,如果left和right⽐较⼤时候可能存在问题,可以使⽤下⾯的⽅式:

mid = left+(right-left)/2;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值