【C语言数组部分】

数组部分综述

  • 引入:
    • 数组概念:
  • 一、一维数组
    • 1.1一维数组的创建:
    • 1.2一维数组的初始化:
      • 1.2.1初始化概念:
      • 1.2.2完全初始化:
      • 1.2.3不完全初始化:
    • 1.3字符数组的初始化:
      • 1.3.1用字符初始化:
      • 1.3.2用字符串初始化:
      • 1.3.3字符数组用字符初始化和字符串初始化的差别:
    • 1.4一维数组的使用(下标引用)
    • 一维数组在内存中的存储:
  • 二、二维数组
    • 2.1二维数组的创建:
    • 2.2二维数组的初始化
    • 2.3二维数组的使用
    • 2.4二维数组在内存中的存储形式
  • 三、数组作为函数参数
    • 冒泡排序(将降序的arr数组排为升序):
      • C语言实现:
    • 注意:

引入:

数组概念:

一类相同类型(整数型/小数型/字母型)元素的集合

一、一维数组

1.1一维数组的创建:

数组元素类型 数组名 [常量表达式]

  • 方括号内必须是常量
  • C99语法支持变长数组(方括号内可以是变量),大部分情况下不建议使用。

1.2一维数组的初始化:

1.2.1初始化概念:

创建的同时并给与相应的值。

1.2.2完全初始化:

  • int arr[10]={1,2,3,4,5,6,7,8,9,10};
  • int arr[]={1,2,3,4,5};等价于int arr[5]={1,2,3,4,5};

1.2.3不完全初始化:

  • int arr[10]={1,2,3,4,5};

1.3字符数组的初始化:

1.3.1用字符初始化:

char ch[5]={‘a’,‘b’,‘c’}; 实际存储:‘a’,‘b’,‘c’,‘\0’,‘\0’

char ch2[]={‘a’,‘b’,‘c’}; 实际存储就是’a’,‘b’,‘c’

1.3.2用字符串初始化:

char ch3[5]=“abc”; 用字符串存储于字符数组:实际存储‘a’,‘b’,‘c’,‘\0’,‘\0’

char ch4[]=“bit”; 实际存储:‘a’,‘b’,‘c’,'\0‘仅有4个元素

##【C语言数组部分】_第1张图片

1.3.3字符数组用字符初始化和字符串初始化的差别:

样例

  • 直观差别

用字符串初始化数组中个数有4个(除了a,b,c还有字符串结束标志’\0’)
【C语言数组部分】_第2张图片

用字符初始化的只有三个元素,没有结尾’\0’
【C语言数组部分】_第3张图片

  • 解析:

打印结果:
【C语言数组部分】_第4张图片
arr2打印乱码原因:

  • 在内存中,arr1用字符串初始字符数组开拓4个空间,打印遇到了字符串结束标志’\0’结束。
  • 在内存中,arr2用字符初始字符数组只开拓3个空间,打印a,b,c过程中没有遇到字符串结束标志。因此会打印字符c后内存中未知的存储内容,直到读到字符串结束标志。

因此求两字符数组的长度时,也会存在差异:
【C语言数组部分】_第5张图片
字符数组arr2的长度是随机值

1.4一维数组的使用(下标引用)

下标引用操作符:[ ]

注意:

  • 数组下标从0开始
  • sizeof(数组名)计算的是整个数组的大小,单位字节

总结:

1:数组用下标访问
2:数组的大小可以计算得到
在这里插入图片描述

一维数组在内存中的存储:

【C语言数组部分】_第6张图片
%p是打印地址格式控制(以16进制打印地址)
【C语言数组部分】_第7张图片
数组元素位置相邻的相差4(字节)
因此

  • 一维数组在内存中连续存放
  • 随数组下标增长,地址增长
  • 找到数组的首地址就可以找到整个数组

又因为数组名即为首元素地址

【C语言数组部分】_第8张图片p++:指向数组中下一元素(在内存中跳过一个该指针变量所指向的元素类型所占的字节数)

二、二维数组

2.1二维数组的创建:

有行有列
【C语言数组部分】_第9张图片
第一个方括号内的数字代表行数,第二个数字代表列数。因此创建的这个数组为3行4列。

2.2二维数组的初始化

  • int arr[3] [4]={1,2,3,4,5,6,7,8,9,10,11,12};
  • 不完全初始化:int arr[3] [4]={1,2,3,4,5,6,7};后边会自动补0
  • 可以看作多个一维数组 :int arr[3] [4]={{1,2},{3,4},{5,6}}每个一维数组不够时补0

注意:
行可以省略
但是列不能省略,因为列决定每行元素的个数(使没行元素个数是确定的)

2.3二维数组的使用

和一维数组相同,都是通过数组的下标来访问数组中的元素:行号从0开始,列号也从0开始
【C语言数组部分】_第10张图片

2.4二维数组在内存中的存储形式

【C语言数组部分】_第11张图片可以观察到,换行时元素在内存中的字节数仍然相差为4.因此——————》

二维数组在内存中本质上也是连续的,每一行内部是连续的,换行时也是连续的(行与行之间也是连续的)。
【C语言数组部分】_第12张图片
只要拿到二维数组中的首元素arr[0[[0]的地址就能找到该二维数组数组所有的元素!
【C语言数组部分】_第13张图片

  • 第一行的元素可以看作arr[0]+0,1,2,3
  • 第二行的元素可以看作arr[1]+0,1,2,3
  • 第三行的元素可以看作arr[2]+0,1,2,3

三、数组作为函数参数

冒泡排序(将降序的arr数组排为升序):

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

使用自定义函数bubble_sort

冒泡排序地思想:
相邻两个元素进行比较,并且可能地话需要交换!
9来到最后时候(排了一趟)

【C语言数组部分】_第14张图片
10个数字,冒泡排序需要进行9趟(9趟后,剩下的一个已经在应该的位置)

如果是n个数字,需要进行n-1趟

第一趟:10个数字待排序,9对比较

第二趟:9个数字的待排序,8对比较

第三趟:8个数字待排序,7对比较

C语言实现:

void bubble_sort(int arr[],int sz)
{
	//1 确定趟数(sz-1趟)
	int i = 0;
	for (i = 0; i < sz - 1; i++)
	{
		//一趟冒泡排序的过程
		int j = 0;
		/*/
		一趟中需要进行比较的对数
		i=0,进行第一趟比较,比较的对数为9
		i=1,进行第二趟比较,比较的对数为8
		*/
		for (j = 0; j < sz-1-i; j++)
		{
			if (arr[j] > arr[j + 1])//前大于后的话就进行交换
			{
				int temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}
}
int main()
{
	int arr[] = { 9,8,7,6,5,4,3,2,1 };
	//计算数组中元素的个数
	int sz = sizeof(arr) / sizeof(arr[0]);
	//冒泡排序
	bubble_sort(arr, sz);
	return 0;
}

注意:

数组传参的时候,传递的本质上传递的是首元素的地址(数组名是数组首元素的地址),形参arr本质上是指针。

x86平台(32位平台)

x64(64位机器)

【C语言数组部分】_第15张图片

》但是有2个例外:

(1)sizeof(数组名):这时的数组名表示的整个数组,计算的是整个数组的大小,单位是字节

(2)&数组名:这时数组名表示整个数组,取出的是整个数组的地址

【C语言数组部分】_第16张图片
打印结果:

【C语言数组部分】_第17张图片

(2)和(3)是相同的

(1)取出的是整个数组的地址,那整个数组的地址和数组首元素的地址一样?

的确一样:打印出的值一样的,意义不一样

【C语言数组部分】_第18张图片

如何显示出&arr和&arr[0](arr)的意义不同:

对&arr+1和&arr[0]+1进行比较

【C语言数组部分】_第19张图片

&arr+1比&arr大了40(16进制的28)

&arr[0]+1比&arr大了4

你可能感兴趣的:(C语言笔记,c语言)