0基础学C语言(3)—— 超详解-->《数组》

在这里插入图片描述

一.初识数组

1.1一维度数组的创建和初始化

  1. 数组传参的时候,传过去仅仅是首元素的地址,

  2. 数组的不完全初始化:没有初始化的默认为0.(数组开在main函数之外的时候)

eg:char arr[5]=“ab”; 前三个分别是 a 、b、 \0

1.2. sizeof 和 strlen的区别:

   char arr1[] = "abc";
   char arr2[] = { 'a','b','c' };  结果
   printf("%d\n", sizeof(arr1));   4
   printf("%d\n", sizeof(arr2));   3
   printf("%d\n", strlen(arr1));   3
   printf("%d\n", strlen(arr2));  随机数

sizeof 计算的是arr所占空间的大小(会包括\0) n个元素*1=n

strlen 求字符串长度 找到\0就停止 并且\0不算入 求\0之前的字符个数

1.简单地说
sizeof计算的是内存空间大小(包括\0) vs strlen计算第一个\0之前的字符串长度(不算\0)

2.sizeof strlen两者没任何关系 一个是关键字 一个是函数

3.strlen只能求字符串长度——并且是库函数,使用时要引头文件

而sizeof是计算变量、数组、类型的大小-单位是字节——本质是操作符/关键字 不需引头文件

1.3一维数组的使用

  • 数组的大小可以通过计算来得到
  • [] 称为 下标引用操作符
  • 这个操作符有什么用呢?
  • 在这里插入图片描述

举个栗子:

`int main()`
`{`
	`int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };`
	`printf("%d", arr[3]);`
	`return 0;`
`}`

当我要执行这个语句: printf("%d", arr[3]);时 打印出来的是什么结果呢?
思考一下 来看答案:在这里插入图片描述
答案是4. 那么为什么这里是4?还有,我上面写着是arr[3],而且中括号里面是依次1-10的排序,为什么不是3呢?

这里有个数组的小细节就是:数组通过下标来访问 并且 元素的下标是从0开始的就像你所看到的1-10的依次排序 谈们的下标依次是0-9
元素:1 2 3 4 5 6 7 8 9 10
下标:0 1 2 3 4 5 6 7 8 9
是这样的对应关系 一定不要搞错

1.4. 一维数组在内存中的储存

  • 数组在内存中是连续存放的,相隔的距离是相同的

二.二维数组的创建和初始化

2.1 二维数组的创建

数组创建`

  `int arr[3][4];`

   `char arr[3][5];`

   `double arr[2][4];``

2.2 二维数组的初始化

//数组初始化

  `int arr[3][4] = {1,2,3,4};`

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

   `int arr[][4] = {{2,3},{4,5}};`

注意:二维数组的行可以省略,但是列不可以省略。并且不能同时省略

2.3 二维数组的使用

二维数组的使用也是通过下标的方式。

eg:

`\#include <stdio.h>`

`int main()`

`{`

 `int arr[3][4] = {0};`

 `int i = 0;`

 `for(i=0; i<3; i++)`

 `{`

 `int j = 0;`

 `for(j=0; j<4; j++)`

 `{`

 `arr[i][j] = i*4+j;`

 `}`

 `}`

 `for(i=0; i<3; i++)`

 `{`

 `int j = 0;`

 `for(j=0; j<4; j++)`

 `{`

 `printf("%d ", arr[i][j]);`

 `}`

 `}`

 `return 0;` 

`}`

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

像一维数组一样,这里我们尝试打印二维数组的每个元素。

`

int arr[3][4];`

`char arr[3][5];`

`double arr[2][4];`

`//数组初始化`

`int arr[3][4] = {1,2,3,4};`

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

`int arr[][4] = {{2,3},{4,5}};`

注意:二维数组在储存中也是连续的,

数组名==首元素地址(有两个例外)
1).sizeof(数组名)——在这里数组名表示整个数组的大小,,sizeof计算的是整个数组的大小,单位是字节.
​2)&数组名,数组名表示整个数组,&数组名,取出的是整个数组的地址

三.数组越界

越界:顾名思义就是超出范围,所以说

  • 数组的下标是有范围限制的。

  • 数组的下标从0——n-1(假设有n个元素)

所以如果数组的下标<0 或者>n-1 我们把它称为数组越界,即超出了数组合法空间的访问

还要注意并且c语言的编译器本身不做数组下标的检查,但即使编译器不报错,并不意味程序就没有错误,所以需要自己做好越界的检查。(二维数组也会存在这种越界的情况)
eg:

#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++)
   {
        printf("%d\n", arr[i]);//当i等于10的时候,越界访问了
   }
 return 0; }

四.数组的应用&&数组与地址、函数的关系:

4.1数组作为函数参数

当我们写代码的时候,有时候需要将数组作为参数传入函数中,举一个最经典的例子:冒泡排序中就需要将数组中的元素排序(整形数组)
我下意识写了一个代码:

#include <stdio.h>//顾冷————CSDN
void bubble_sort(int arr[])
{
 int sz = sizeof(arr)/sizeof(arr[0]);//这样对吗?
    int i = 0;
 for(i=0; i<sz-1; i++)
   {
        int j = 0;
        for(j=0; j<sz-i-1; j++)
       {
            if(arr[j] > arr[j+1])
           {
                int tmp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = tmp;
           }
       }
   }
}
int main()
{
    int arr[] = {3,1,7,5,8,9,0,2,4,6};
    bubble_sort(arr);//是否可以正常排序?
    for(i=0; i<sizeof(arr)/sizeof(arr[0]); i++)
   {
        printf("%d ", arr[i]);
   }
    return 0; }//CSDN---顾冷

很显然跑出来的结果是错误的
那么我们要深入了解:

4.2数组名是什么?

随后当我debug的时候发现,bubble_sort内部的sz的大小是1,这里我就很纳闷,为什么数组作为参数的时候不是把整个数组给传递过去呢?如果不是整个数组传过去,那么是传过去了什么呢?
随后上CSDN看大佬们的博客 (上网冲浪)之后,才知道这里传过去的数组名等于首元素的地址 即arr==&arr[0]
其本质就是一个指针 并且大小为4 这么看来 sz==1(整形,指针的大小都是1)这个结果也不足为怪了。
于是 善于总结的我 知道了:
数组名是首元素的地址

补充:
arr 、 arr[0] 都是首元素的地址
但是 &arr 就是整个数组的地址

既然数组名是首元素地址,那么:

int arr[10] = {0};
printf("%d\n", sizeof(arr));

我们都知道,所有东西都不一定是绝对的,当然此处也有2个例外
eg:

  1. sizeof(数组名),计算整个数组的大小,sizeof内部单独放一个数组名,数组名表示整个数 组。
  2. &数组名,取出的是数组的地址。&数组名,数组名表示整个数组。

综上,可以得出结论:除了1.2补充的情况外,所有的数组名都表示数组首元素的地址。

4.3冒泡函数的正确编程

我在#4.1数组作为函数参数中 写的代码是有问题的(数组传到函数中变成了指针,实际上传过去的arr只是一个摆设 首地址的地址

即使在函数参数部分写成数组的形式: int arr[] 表示的依然是一个指针: int *arr 。

那么应该怎么修改呢?
首先还是要清楚之前的错误在于 传过去的形参相当于是一个指针了,那么计算sz==_____,的时候就会出现错误,那么我们可不可以先计算出sz,再将sz传到函数中进行计算呢?速度上手试一波
eg://顾冷csdn


```c

```c
```c
void bubble_sort(int arr[], int sz)//参数接收数组元素个数
{
	int i = 0;
	for (i = 0; i < sz - 1; i++)
	{
		//每一趟冒泡排序
		int flg = 1;//假设要排的数据已经有序
		int j = 0;
		for (j = 0; j < sz - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tep = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tep;
				flg = 0;//本次的排序其实不完全有序
			}

			
		}
		if (flg == 1)
		{
			break;
		}
	}
}
int main()
{
    int arr[] = {3,1,7,5,8,9,0,2,4,6};
    int sz = sizeof(arr)/sizeof(arr[0]);
     bubble_sort(arr, sz);//在这里看看,是否可以正常排序?
    for(i=0; i<sz; i++)
   {
        printf("%d ", arr[i]);
   }
    return 0; 
    }

数组的应用(五子棋与扫雷)

时间关系 ,所以这里先鸽~,之后补上详细的应用知识
谢谢大佬们的观看和点赞,如果发现有什么错误的地方请在评论区指出
笔者在此感激不尽~

  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值