C语言学习记录—数组

本章节分为:一维数组创建和初始化、二维数组创建和初始化、数组越界、数组作为函数参数。

第一节:一维数组创建和初始化

数组就是一组相同类型元素的集合。

1. 一维数组创建方式:数组的元素类型+数组名+数组大小(需要常量表达式)
int arr[10];
char ch[5];
double data1[20];
double data2[15 + 5];

值得注意的是,C99之前[ ]中只能使用常量。C99之后才支持变长数组,[ ]中可以使用变量,但是这种数组不能初始化。

2. 一维数组初始化:
int main()
{
	//不完全初始化,剩余的元素默认初始化为0
	int arr1[10] = { 1,2,3 };
	//完全初始化
	int arr2[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr[] = { 1,2,3 };//3个元素


	//放进去10个元素之后是否是字符串,取决于末尾是否是\0结束
	//否则不能以字符串的形式打印
	char arr1[10] = { 'a','b','c' };
	//a b c 0 0 0 0 0 0
	char arr2[10] = "abc";
	//a b c \0 0 0 0 0 0 0
	char arr3[] = { 'a','b','c' };//3个元素
	char arr4[] = "abc";//4个元素 末尾有\0
	return 0;
}

3. 一维数组的使用:
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	//[] - 下标引用操作符
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	
	printf("%d\n", arr[4]);//打印下标是4的元素 结果是:5
	for (i = 0; i < sz; i++)//打印数组每个元素
	{
		printf("%d ", arr[i]);
	}
	
	//倒序打印
	for (i = sz - 1; i >= 0; i--)
	{
		printf("%d ", arr[i]);
	}

4. 一维数组在内存中的储存
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
 
    for (i = 0; i < sz; i++)
	{
		printf("&arr[%d] = %p\n", i, &arr[i]);
	}

	//& arr[0] = 0000007C5B6FF9A8
	//& arr[1] = 0000007C5B6FF9AC
	//& arr[2] = 0000007C5B6FF9B0
	//& arr[3] = 0000007C5B6FF9B4
	//& arr[4] = 0000007C5B6FF9B8
	//& arr[5] = 0000007C5B6FF9BC
	//& arr[6] = 0000007C5B6FF9C0
	//& arr[7] = 0000007C5B6FF9C4
	//& arr[8] = 0000007C5B6FF9C8
	//& arr[9] = 0000007C5B6FF9CC

可以看到,随时数组下标递增,元素的地址也在有规律的递增,因为int类型是4字节,所以每次增加4。结论是:数组在内存中是连续存放的。

第二节:二维数组的创建和初始化

1. 二维数组的创建
	int arr1[3][4];//3行4列
	char arr2[5][10];//5行,每行10个字符

2. 二维数组的初始化
	//未分组时,每行自动放4个
	int arr1[3][4] = { 1,2,3,4,2,3,4,5,3,4,5,6 };
	
    //如果初始化元素不够,剩下自动补0
	int arr2[3][4] = { 1,2,3,4,2,3,4,5,3,4};
	
    //每行剩余两个自动补0
	int arr3[3][4] = { {1,2},{3,4},{5,6} };
	
    //可以省略行,但不能省略(列)每行有几个元素,如果每列元素不足,自动补0
	//这种情况必须初始化,省略列就没法确认基本存放方式
	int arr4[][4] = { {1,2,3,4},{5,6} };//等效int arr4[][4] = { 1,2,3,4,5,6 };

3. 二维数组的使用
	int arr[3][4] = { 1,2,3,4,2,3,4,5,3,4,5,6 };
	int i = 0;
	
	//向二维数组输入数据
	for (i = 0; i < 3; i++)
	{
		int j = 0;
		for (j = 0; j < 4; j++)
		{
			scanf("%d", &arr[i][j]);
		}
	}

	//打印二维数组
	for (i = 0; i < 3; i++)
	{
		int j = 0;
		for (j = 0; j < 4; j++)
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}

4. 二维数组在内存的储存

本质上二维数组还是一维数组,所以每一行的元素所占内存空间大小必须相等,所以每一行的元素个数必须要相等。

	int arr[3][4] = { 1,2,3,4,2,3,4,5,3,4,5,6 };
	int i = 0;

	for (i = 0; i < 3; i++)
	{
		int j = 0;
		for (j = 0; j < 4; j++)
		{
			printf("&arr[%d][%d] = %p\n", i, j, &arr[i][j]);
		}
	}

	//&arr[0][0] = 010FFE20
	//&arr[0][1] = 010FFE24
	//&arr[0][2] = 010FFE28
	//&arr[0][3] = 010FFE2C
	//&arr[1][0] = 010FFE30
	//&arr[1][1] = 010FFE34
	//&arr[1][2] = 010FFE38
	//&arr[1][3] = 010FFE3C
	//&arr[2][0] = 010FFE40
	//&arr[2][1] = 010FFE44
	//&arr[2][2] = 010FFE48
	//&arr[2][3] = 010FFE4C

第三节:数组越界

数组的下标是0~n-1。C语言本身不做数组下标的越界检查,编译器也不一定报错。所以写代码时,要做好越界检查。

第四节:数组作为函数参数

这里使用冒泡排序作为例子。

这里需要注意,不能在函数内部直接使用sizeof(arr)计算数组大小。因为数组传参时,传递的是数组首元素的地址。

//数组传参的时候,形参有两种写法:
//1.数组形式
//2.指针形式


void bubble(int* arr, int sz)
{
	int i = 0;//i是需要交换多少轮
	for (i = 0; i < sz - 1; i++)
	{
		//j是元素下标,从下标为0的元素(也就是第一个元素)开始逐一比较
		//第1轮:第1个元素需要交换 元素个数-1次,10-1=9
		//第2轮:第2个元素需要交换 元素个数-2次,10-2=9
		//....
		//第9轮:第9个元素需要交换 元素个数-9次,10-9=1
		//结束,总共交换 元素个数-1轮,10-1=9
		int j = 0;
		for (j = 0; j < sz - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}

}
int main()
{
	int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);

	bubble(arr, sz);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}

	return 0;
}

作业

1. 若定义int a[2][3] = { 1,2,3,4,5,6 }; 则值为4的数组元素是()

A.a[0][0]
B.a[1][0]
C.a[1][1]
D.a[2][1]
答案:B
 

2. 定义了一维 int 型数组 a[10] 后,下面错误的引用是:(   )

A.a[0] = 1;
B.a[0] = 5 * 2;
C.a[10] = 2;
D.a[1] = a[2] * a[0];
答案:C
 

3. 以下能对二维数组a进行正确初始化的语句是:(    )

A.int a[2][] = { {0,1,2},{3,4,5} };
B.int a[][3] = { {0,1,2},{3,4,5} };
C.int a[2][4] = { {0,1,2},{3,4},{5} };
D.int a[][3] = { {0,,2},{},{3,4,5} };
答案:B
 

4. 关于一维数组初始化,下面哪个定义是错误的?( )

A.int arr[10] = { 1,2,3,4,5,6 };
B.int arr[] = { 1,2,3,4,5,6 };
C.int arr[] = (1, 2, 3, 4, 5, 6);
D.int arr[10] = { 0 };
答案:C
 

5. 关于一维数组描述不正确的是:( )

A.数组的下标是从0开始的
B.数组在内存中是连续存放的
C.数组名表示首元素的地址
D.随着数组下标的由小到大,地址由高到低
答案:D
 

6. 冒泡排序

实现一个对整形数组的冒泡排序

int main()
{
	int arr[10] = { 1,3,2,5,4,8,7,9,6,10 };

	int i = 0;//要交换的轮数(n-1)
	int j = 0;//每轮要交换的次数(n-1-i)
	int sz = sizeof(arr) / sizeof(arr[0]);//数组元素个数

	for (i = 0; i < sz - 1; i++)
	{
		int flag = 0;
		for (j = 0; j < sz - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
				flag = 1;
			}
		}
		if (0 == flag)
			break;
	}

	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

7. 使用函数实现数组操作

创建一个整形数组,完成对数组的操作
实现函数init() 初始化数组为全0
实现print()  打印数组的每个元素
实现reverse()  函数完成数组元素的逆置。
要求:自己设计以上函数的参数,返回值。
 

void init(int arr[], int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		arr[i] = 0;
	}
}

void print(int arr[], int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
}

void revese(int arr[], int sz)
{
	int left = 0;
	int right = sz - 1;
	while (left < right)
	{
		int tmp = arr[left];
		arr[left] = arr[right];
		arr[right] = tmp;
		left++;
		right--;
	}
}
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int sz = sizeof(arr) / sizeof(arr[0]);

	//memset(arr, 0, sizeof(arr));
	init(arr, sz);
	print(arr, sz);
	revese(arr, sz);

	return 0;
}

8. 一维数组】交换数组

将数组A中的内容和数组B中的内容进行交换。(数组一样大)

int main()
{
	int arr1[10] = { 0 };
	int arr2[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		int tmp = arr1[i];
		arr1[i] = arr2[i];
		arr2[i] = tmp;
	}
	for ( i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
	printf("\n");
	for ( i = 0; i < 10; i++)
	{
		printf("%d ", arr2[i]);
	}
	return 0;
}

9. 下面代码的结果是:( )

int main()
{
    char str[] = "hello bit";
    printf("%d %d\n", sizeof(str), strlen(str));
    return 0;
}
//A. 10 9
//B. 9 9
//C. 10 10
//D. 9 10
//答案:A

10. 下面代码的结果是:(  )

int main()
{
    int arr[] = { 1,2,(3,4),5 };
    printf("%d\n", sizeof(arr));
    return 0;
}
//A.4
//B.16
//C.20
//D.5
//答案:B

11. 给出以下定义:

char acX[] = "abcdefg";
char acY[] = { 'a','b','c','d','e','f','g' };
//以下说法正确的是()
//A.数组acX和数组acY等价
//B.数组acX和数组acY的长度相同
//C.sizeof(acX) > sizeof(acY)
//D.strlen(acX) > strlen(acY)
//答案:C
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值