C语言学习(三) 数组

1. 一维数组

正如第一节中所说的那样,数组有三个特征点:数组名、数组元素数据类型、数组元素个数

数组是内存中一段连续存储的内存单元,在编译的时候才对其分配内存空间

1.1 一维数组的定义和初始化

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

类似于上面这条语句,一般都是这样定义的:

数据类型 数组名称 [ 数组元素数量 ]   =   {  初始化的值  };

也可以不需要初始化,在后面的过程中进行初始化即可

 1.2 一维数组的使用

使用一维数组的时候可以使用数组名加下标、指针一共两种方式来访问数组中元素的个数

比如下面两段程序:

#include<stdio.h>

void fun(int* a, int length) {
	for (int i = 0; i < length; i++) {
		a[i] = i;
	}
}


int main() {
	int ar[3] = { 1,2,3 };

	int* p = ar;
	printf("%d %d", ar[1], *(p + 1));// 2 2

	fun(ar, 3);

	return 0;
}

上面代码看懂了,那么对于数组的两种使用方法也就掌握了

注意点:

1. 两个数组的数组名不能直接赋值,比如两个数组ar 和 br,不能把 br = ar,这样是错误的

2. 定义数组的时候不能找一个变量名定义数量,应该是一个整型字面常量,比如不能

int n = 4;
int ar[n] = {1 , 2 , 3 , 4};

 

1.3 一维数组的应用

其应用最广的就是查表法,下面介绍几个查表法实现的例子,来体会:

1.3.1 闰年、判断某年某月有多少天、判断某年某月某日之前有多少天

//判断某年是不是闰年
bool is_leap(int year) {
	return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}

//判断某年某月有多少天
int YearMonth_To_Day(int year, int month){
    //定义一个天数的表格,0代表如果是闰年的时候,二月取的值,2代表正常状况下二月取得值
	static const int day[] = { 29, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    //判断如果为闰年且为2月那么就让month赋值为0
	if (month == 2 && is_leap(year)) {
		month = 0;
	}
	return day[month];
}

//告诉年月日计算出之前共有多少天
int Get_YMD_To_Sum(int year, int month, int day) {
    //定义一个天数的表格,分别表示month为某个数时,其之前所有月份加一块共有多少天
    //如果是闰年且month大于2,那么总天数还需要+1
	static const int sum[] = { 0,0,31,59,90,120,151,181,212,243,273,304,334,365 };
    //如果年号不符合规则 return -1
	if (year < 1) {
		return -1;
	}
    //如果月份不符合规则 return -2
	if (month < 1 || month> 12) {
		return -2;
	}
    //如果天数不符合规则 return -3
	if (day< 1 || day> YearMonth_To_Day(year, month)) {
		return -3;
	}
	int total = sum[month] + day;
    //如果是闰年,并且月份大于2,那么将总天数+1
	if (month > 2 && is_leap(year)) {
		total += 1;
	}
					
	return total;
}

1.3.2 定义大小为 100的整型数组,使用随机函数给数组元素赋值。数值范围1....100,并且排序,使用冒泡排序实现

//打印整型数组
void show_Array(int* arr, int n) {
	int count = 0;
	for (int i = 0; i < n; ++i) {
        //每五行打印一个换行
		if (count % 5 == 0) {
			printf("\n");

		}
		printf("%d\t", arr[i]);
		count++;
	}
}
//对一个整型数组用冒泡排序实现排序
void Bubble_Sort(int* arr,int n) {
	int m, i, j;
	for (i = 0; i < n - 1; i++){
		for (j = 0; j < n - 1 - i; j++){
			if (arr[j] > arr[j + 1])
			{
				m = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = m;
			}
		}
	}
}
//获取随机数1-100的数组,并且冒泡排序,打印
void get_Array(int n) {
	if (n < 1) {
		return;
	}
	int arr[100];
	for (int i = 0; i < 100; i++) {
        //利用rand函数生成1~100的数
		arr[i] = rand() % 100 + 1;
	}
    //对数组进行冒泡排序
	Bubble_Sort(arr, 100);
	printf("获取随机数1-100的数组,并且冒泡排序,打印:\n");
    //打印数组
	show_Array(arr, 100);
	printf("\n\n\n");
}

1.3.3 定义大小为 100的整型数组,使用随机函数给数组元素赋值。数值范围1....100,并且要求没有重复

1.3.3.1 查表法

//定义大小为100的整型数组,数值范围为1-n
//不允许有重复
void get_Array_NoSame(int n) {
    //定义一个标志数组,对于每一个数进行记录,如果之前生成过
    //那就让其对应下标处的数改为1
	int flag[100] = { 0 };
	if (n < 1) {
		return;
	}
	int arr[100];
	for (int i = 0; i < 100; i++) {
		int n = rand() % 100 + 1;
        //判断生成的随机数n之前是否已经生成过
        //如果已经生成过再次生成新的数字,直到生成随机数之前没有出现过为止
		while (flag[n-1] == 1) {
			n = rand() % 100 + 1;
		}
        //如果生成了之前没生成的数字
        //那么就将其插入到arr数组中
		arr[i] = n;
        //令该数处的flag值为1
		flag[arr[i]-1] = 1;
	}
	Bubble_Sort(arr, 100);
	printf("获取随机数1-100的数组,不能有重复,并且冒泡排序,打印:\n");
	show_Array(arr, 100);
	printf("\n\n\n");
}

1.3.2 哈希表法

见下一节单独写的博客

2. 二维数组

2.1 二维数组的定义

类型名     数组名[ 行表达式 ] [ 行表达式 ] 

2.2 二维数组的逻辑和内存表示

2.2.1 二维数组在内存中的映像

 

  • 一维数组int a[10]与二维数组int b[2][5]的对应关系
一维数组a[0]a[1]a[4]a[5]a[9]
二维数组b[0][0]b[0][1]b[0][4]b[1][0]b[1][4]

一个二维数组a[m]可以表示为二维数组a[x][y] ,这里面m = x * y

任意二维数组中的元素a[i][j]在一维数组中对应的下标k为:

k = i * y + j,即 a[ i ][ j ] == a[ k ] == a[ i * y + j ]

 

2.3 二维数组的访问方式

下标式访问:a[i][j]

指针式访问:*(*(a + i) + j)

2.4 二维数组的初始化

对于二维数组,其在内存中是连续存放的,对于没初始化到的元素会自动添0来赋初值

对于二维数组的初始化,第一维的长度可以省略,第二维不可缺省

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

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值