跟着鹏哥学编程,拿一个好offer。
今天的学习内容是数组,在此记录一下,也相当于是复习。
数组有一维数组、二维数组和多维数组。首先介绍一维数组,定义一个数组如下:
#include <stdio.h>
int main()
{
int arr[10]={1,2,3,4,5,6,7,8,9,10};
return 0;
}
从上面示例可见,我定义了一个可以存放10个整型数的数组,并进行了初始化,数组名是arr。数组名在通常情况下是数组首元素的地址,但有两种特殊情况。第一种情况是在sizeof(数组名),这个时候数组名代表的是整个数组;第二种情况是对数组名取地址,即&arr,这个时候取的地址是整个数组的地址,而不是数组首元素地址。int arr[数组大小];这里,数组大小必须是整型常量,不能是变量,也不能像下面一样定义数组大小。
#include <stdio.h>
int main()
{
int n=10;
int arr[10]={1,2,3,4};
return 0;
}
像这样定义一个变量,再将变量值传给数组也是不合法的。上面是这数组是不完全初始化,未初始化的部分默认初始化为零。
一维数组的使用可以放在循环中使用,如下例所示。
#include <stdio.h>
int main()
{
int arr[10]={1,2,3,4,5};
int i=0;
int sz=sizeof(arr)/sizeof(arr[0]);//求数组元素个数
//在for循环中将数组arr打印出来
for(i=0;i<sz;i++)
{
printf("%d ",arr[i]);
}
return 0;
}
接下来说说二维数组,二维数组的定义、初始化和使用如下所示。
#include <stdio.h>
int main()
{
//定义一个3行4列的二维数组arr1
//它被初始化只有第一行和第二行
//1 2 3 4
//5 6 7 8
//剩余一行默认被初始化为零
int arr1[3][4] = {1,2,3,4,5,6,7,8};
int i = 0; int j = 0;
for (i = 0; i < 3; i++) //控制行数
{
for (j = 0; j < 4; j++)//控制列数
{
printf("%d ",arr1[i][j]);
}
if (j % 4 == 0)//列数j=4时换行,便于观察
printf("\n");
}
//如下定义了一个3行4列二维数组arr2
//如下初始化了该二维数组的每一行的前两个元素
int arr2[3][4] = { {1,2},{3,4},{4,5} };
return 0;
}
运行结果图如下:
如上结果图可见,我们所定义和初始化的二维数组是符合我的预期要求的。
二维数组在定义和初始化时是形如int arr[const m][const n];但是它在内存中存储时还是占用连续的一片空间,而且是第一行存完接着存第二行直到将所有元素存起来,所以可以将一个二维数组的每一行又可以看作是一个一维数组。
接下来用数组作为函数参数,复现一下经典排序方法——冒泡排序方法,先给出它的初级版如下:
#include <stdio.h>
void bubble_sort(int arr[], int sz)
{
int i = 0;
//int sz = sizeof(arr) / sizeof(arr[0]);//计算元素个数;
/*
如果在这里计算,由于数组传参时传递的是数组首元素地址,既然是地址,那就可以看作是一个指针,
指针变量占用四个字节,二arr数组存放的是整型数,每个元素占用四个字节,最后sz=1,不满足for
循环,那就更不能进行冒泡排序了
*/
for (i = 0; i < sz - 1; i++)
//数组如果有sz个元素,则冒泡排序共要进行sz-1趟排序
{
int j = 0;
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[] = {3,5,4,7,8,1,10,9,12};
/*
这里只能在main()函数中将数组元素个数计算出来,然后传给bubble_sort()函数,
而不能在bubble_sort()函数中计算(具体见bubble_sort()函数中)
*/
int sz = sizeof(arr) / sizeof(arr[0]);//计算元素个数;
bubble_sort(arr,sz);
int i = 0;
printf("冒泡排序后的数组:");
for (i = 0; i < sz; i++)
{
printf("%d ",arr[i]);
}
return 0;
}
初级版的冒泡排序方法虽然能够满足排序要求,但是可以看出他的效率是很低的,因为若果数组是有序的话,他还有一趟一趟的运算,那聪明的人类想了很多办法优化这个代码,这里就给出我熟悉的一个优化方法。
#include <stdio.h>
//升级版冒泡排序法
void bubble_sort(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz - 1; i++)
{
//定义一个标志,用于判断是否要进行冒泡排序
//假定数组元素为8 1 2 3 4 5 6 7时
//在进行第一趟冒泡排序的时候,进入到下面的for()循环,flag=0;
int flag = 1;
int j = 0;
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;
flag = 0;
}
}
//第一趟冒泡排序后,数组元素顺序为:1 2 3 4 5 6 7 8
//这时flag=1,满足下面if语句,break跳出最外面循环,冒泡排序结束
if (flag == 1)
{
break;
}
}
}
int main()
{
int arr[] = {3,5,4,7,8,1,10,9,12};
int sz = sizeof(arr) / sizeof(arr[0]);//计算元素个数;
bubble_sort(arr,sz);
int i = 0;
printf("冒泡排序后的数组:");
for (i = 0; i < sz; i++)
{
printf("%d ",arr[i]);
}
return 0;
}