数组
为啥有数组
在程序设计中,为了方便处理数据把具有相同类型的若干变量按有序形式组织起来——称为数组。
数组就是在内存中连续的相同类型的变量空间。同一个数组所有的成员都是相同的数据类型,同时所有的成员在内存中的地址是连续的。
一维数组
- 数组名字符合标识符的书写规定(数字、英文字母、下划线)
- 数组名不能与其它变量名相同,同一作用域内是唯一的
- 方括号 [ ] 中常量表达式表示数组元素的个数
- int a[3]表示数组a有3个元素。其下标从0开始计算,因此3个元素分别为a[0],a[1],a[2]
- 定义数组时[]内最好是常量,使用数组时[]内即可是常量,也可以是变量
#include <stdio.h>
int main()
{
int a[10];//定义了一个数组,名字叫a,有10个成员,每个成员都是int类型
//a[0]…… a[9],没有a[10]
//没有a这个变量,a是数组的名字,但不是变量名,它是常量
a[0] = 0;
//……
a[9] = 9;
int i = 0;
for (i = 0; i < 10; i++)
{
a[i] = i; //给数组赋值
}
//遍历数组,并输出每个成员的值
for (i = 0; i < 10; i++)
{
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
输出:
0 1 2 3 4 5 6 7 8 9
一维数组的初始化
在定义数组的同时进行赋值,称为初始化。
全局数组若不初始化,编译器将其初始化为零;局部数组若不初始化,内容为随机值。
int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; //定义一个数组,同时初始化所有成员变量
int a[10] = { 1, 2, 3 }; //初始化前三个成员,后面所有元素都设置为0
int a[10] = { 0 }、; //所有的成员都设置为0
//[]中不定义元素个数,定义时必须初始化
int a[] = { 1, 2, 3, 4, 5 };//定义了一个数组,有5个成员
一维数组的最值
#include <stdio.h>
int main()
{
int a[] = { 1, -2, 3,-4, 5, -6, 7, -8, -9, 10 };//定义一个数组,同时初始化所有成员变量
int i = 0;
int max = a[0];
for (i = 1; i < sizeof(a) / sizeof(a[0]); i++)
{
if (a[i] > max)
{
max = a[i];
}
}
printf("数组中最大值为:%d\n", max);
return 0;
}
输出:
数组中最大值为:10
一维数组的逆置
#include <stdio.h>
int main()
{
int a[] = { 1, -2, 3,-4, 5, -6, 7, -8, -9, 10 };//定义一个数组,同时初始化所有成员变量
int i = 0;
int j = sizeof(a) / sizeof(a[0]) - 1;
int tmp;
while (i < j)
{
tmp = a[i];
a[i] = a[j];
a[j] = tmp;
i++;
j--;
}
for (i = 0; i < sizeof(a) / sizeof(a[0]); i++)
{
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
输出:
10 -9 -8 7 -6 5 -4 3 -2 1
冒泡法排序
#include <stdio.h>
int main()
{
int a[] = { 1, -2, 3,-4, 5, -6, 7, -8, -9, 10 };//定义一个数组,同时初始化所有成员变量
int i = 0;
int j = 0;
int n = sizeof(a) / sizeof(a[0]);
int tmp;
//1、流程
//2、试数
for (i = 0; i < n - 1; i++)
{
for (j = 0; j < n - i - 1; j++)//内循环的目的是比较相邻的元素,把大的放到后面
{
if (a[j] > a[j + 1])
{
tmp = a[j];
a[j] = a[j + 1];
a[j + 1] = tmp;
}
}
}
for (i = 0; i < n; i++)
{
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
输出:
-9 -8 -6 -4 -2 1 3 5 7 10
二维数组
二维数组在概念上是二维的:其下标在两个方向上变化,对其访问一般需要两个下标。
在内存中并不存在二维数组,二维数组实际的硬件存储器是连续编址的,也就是说内存中只有一维数组,即放完一行之后顺次放入第二行,和一维数组存放方式是一样的。
二维数组的初始化
//分段赋值
int a[3][4] = {{ 1, 2, 3, 4 },{ 5, 6, 7, 8, },{ 9, 10, 11, 12 }};
int a[3][4] =
{
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8, },
{ 9, 10, 11, 12 }
};
//连续赋值 【注意:a[i][j] 列不能省略,不然程序不能分析出具体怎么分配数据】
int a[3][4] = { 1, 2, 3, 4 , 5, 6, 7, 8, 9, 10, 11, 12 };
int a[][4] = { 1, 2, 3, 4, 5, 6, 7, 8 }; //[]中不定义元素个数,定义时必须初始化
//可以只给部分元素赋初值,未初始化则为0
int a[3][4] = { 1, 2, 3, 4 };
//所有的成员都设置为0
int a[3][4] = { 0 };
数组名是一个地址的常量,代表数组中首元素的地址
#include <stdio.h>
int main()
{
//定义了一个二维数组,名字叫a
//二维数组是本质上还是一维数组,此一维数组有3个元素
//每个元素又是一个一维数组int[4]
int a[3][4] = { 1, 2, 3, 4 , 5, 6, 7, 8, 9, 10, 11, 12 };
//数组名为数组首元素地址,二维数组的第0个元素为一维数组
//第0个一维数组的数组名为a[0]
printf("a = %p\n", a);
printf("a[0] = %p\n", a[0]);
//测二维数组所占内存空间,有3个一维数组,每个一维数组的空间为4*4
//sizeof(a) = 3 * 4 * 4 = 48
printf("sizeof(a) = %d\n", sizeof(a));
//测第0个元素所占内存空间,a[0]为第0个一维数组int[4]的数组名,4*4=16
printf("sizeof(a[0]) = %d\n", sizeof(a[0]));
//测第0行0列元素所占内存空间,第0行0列元素为一个int类型,4字节
printf("sizeof(a[0][0]) = %d\n", sizeof(a[0][0]));
//求二维数组行数
printf("i = %d\n", sizeof(a) / sizeof(a[0]));
// 求二维数组列数
printf("j = %d\n", sizeof(a[0]) / sizeof(a[0][0]));
//求二维数组行*列总数
printf("n = %d\n", sizeof(a) / sizeof(a[0][0]));
return 0;
}
数组名就是首地址
- 一维数组
#include <stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
//下标为0的元素地址
printf("%p\n", &arr[0]);
//数组名是一个地址常量 指向数组首地址的常量
printf("%p\n",arr);
return 0;
}
输出:
012FFD44
012FFD44
- 二维数组
#include <stdio.h>
int main()
{
int arr[2][3] = {
{1,2,3},
{4,5,6}
};
//二维数组首地址
printf("%p\n", arr);
printf("%p\n", &arr[0]);
printf("%p\n", &arr[0][0]);
printf("%p\n", &arr[1]);
return 0;
}
输出:
008FFC20
008FFC20
008FFC20
008FFC2C
注意
int arr[5] = {1}
打印出来的是:1 0 0 0 0 没有初始化,默认就是0
int arr[5];
arr[0] = 1;
打印出来的是:1 23242 234234 234234 234234 后面四个是乱码(每次打印出来的不一样)
参考:
[1]C基础讲义2018修订版(黑马程序员)