目录:
数组的定义
所谓数组,是有序的元素序列。 若将有限个类型相同的变量的集合命名,那么这个名称为数组名。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。用于区分数组的各个元素的数字编号称为下标。数组是在程序设计中,为了处理方便, 把具有相同类型的若干元素按无序的形式组织起来的一种形式。 这些无序排列的同类数据元素的集合称为数组。
数组是用于储存多个相同类型数据的集合。 —— [ 360百科 ]
一、一维数组
1.1 一维数组的创建初始化
数组的创建方式:type_t arr_name [const_n]
其中type_t
表示的是数组中元素的类型,arr_name
指的是数组所起的名字,后面,的const_n
是一个常量表达式,用来指定数组的大小,以下是数组的创建实例:
int arr1[10];
float arr2[20];
一般情况下在数组创建的同时都会对其相应的进行初始化,只有初始化了的数组,内存才会给其分配空间,数组才能正常使用
初始化有两种
- 完全初始化
int arr[10] = {0,1,2,3,4,5,6,7,8,9};
- 不完全初始化
int arr[10] = {1,2,3};//未初始化的空间则默认初始化为0
1.2 一维数组的使用
数组在使用时大都采用下标引用操作符 [ ]
#include <stdio.h>
void Init(int arr[],int sz)//使用下标引用操作赋,通过循环遍历整个数组对其进行初始化
{
int i = 0;
for (i=0; i<sz; i++)
{
arr[i] = 0;
}
}
void my_print(int arr[],int sz)//打印数组
{
int i = 0;
for (i=0; i<sz; i++)
{
printf("%d ",arr[i]);
}
}
void Reverse(int arr[],int sz)//数组的逆置
{
int left = 0;
int right = sz-1;
int tmp = 0;
while (left<right)
{
tmp = arr[left];
arr[left] = arr[right];
arr[right] = tmp;
left++;
right--;
}
}
int main()
{
int arr[10];
int size = sizeof(arr)/sizeof(arr[0]);
int i = 0;
Init(arr,size);
for (i=0; i<size; i++)//数组的赋值
{
arr[i] = i;
}
my_print(arr,size);
printf("\n");
Reverse(arr,size);
my_print(arr,size);
printf("\n");
return 0;
}
二、二维数组
2.1 二维数组的创建和初始化
二维数组与一维数组类似,我们可以将其想象成在空间是多行多列的
- 创建
int arr1[3][4];//三行四列
doble arr2[5][5];
- 初始化
同样二维数组的初始化也分为完全初始化和不完全两种,一维数组初始化和创建同时进行时int arr[] = {1,2,3};
可以省略数组大小部分,通过后面初始化的元素个数来确定其大小,采用此种方法创建+初始化数组,就必须保证数组的行列常量和初始化后面的信息加起来能唯一确定数组形式,如int arr[][3] = {{1,3},{2,4}};
虽没有给出行数,但根据后面的初始化内容可以确定有两行,所以该数组是两行三列
2.2 二维数组的使用
二维数组的使用与一维数组相同,通过两层for循环使用下表引用操作符
#include <stdio.h>
int main()
{
int arr[10][10] = {0};//数组的创建+不完全初始化
int i = 0;
int j = 0;
//通过下标递增赋值
for(i=0; i<10; i++)
{
for(j=0; j<10; j++)
{
arr[i][j] = i*10+j;
}
}
//循环打印
for(i=0; i<10; i++)
{
for(j=0; j<10; j++)
{
printf("%4d", arr[i][j]);
}
printf("\n");
}
return 0;
}
三、数组的指针访问
3.1 数组在内存中的存储
一维数组在内存中的存储
int为4个字节,可见其为连续存放
二维数组在内存中的存放
与一维数组一样,同样为连续存放
3.2 数组的指针访问
因为一维数组和二维数组在内存中的存放形式相同,那么均可以通过指针进行访问
一维数组的指针访问
二维数组的指针访问
四、有关数组的运算
有关数组的操作有以下几种
- 1.sizeof(数组名)–数组名相当于整个数组,sizeof(数组名)计算的是整个数组的大小,单位是字节
2.&数组名,取出的是数组的地址除此之外的所有数组名都是首元素的地址
3.数组在函数传参过程中传的是首元素的地址
下面有一组运算题,可以很好的熟悉这些知识:
int a[] = {1,2,3,4};
printf("%d\n",sizeof(a)); //整个数组大小 16
printf("%d\n",sizeof(a+0));//a[0]地址 4
printf("%d\n",sizeof(a+1));//a[1]地址 4
printf("%d\n",sizeof(a[1]));//元素a[2]的类型大小(int) 4
printf("%d\n",sizeof(&a)); //取出数组的地址 4
printf("%d\n",sizeof(*&a));//取出整个数组的地址解引用找到所有元素 16
printf("%d\n",sizeof(&a+1));//用于存放数组地址的指针变量的下一个地址 4
printf("%d\n",sizeof(&a[0]));//第一个元素的地址 4
printf("%d\n",sizeof(&a[0]+1));//第二个元素的地址 4
运算结果:
char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", sizeof(arr));//整个数组大小 6
printf("%d\n", sizeof(arr+0));//第一个元素地址 4
printf("%d\n", sizeof(*arr));//第一个元素类型大小 1
printf("%d\n", sizeof(arr[1]));//第二个元素类型大小 1
printf("%d\n", sizeof(&arr));//整个数组的地址 4
printf("%d\n", sizeof(&arr+1));//用于存放数组地址的内指针变量的下一个地址 4
printf("%d\n", sizeof(&arr[0]+1));//第二个元素的地址 4
printf("%d\n", strlen(arr));//首元素地址往后找,后\0未知是一个随机值 x
printf("%d\n", strlen(arr+0));//首元素地址往后找,后\0未知是一个随机值 x
printf("%d\n", strlen(*arr));//*arr是第一个元素,不是地址不符合strlen参数要求
printf("%d\n", strlen(arr[1]));//arr[1]是第二个元素,不是地址不符合strlen参数要求
printf("%d\n", strlen(&arr));//存放数组地址的指针变量地址(数值上等于首元素地址)往后找,后\0未知是一个随机值 x
printf("%d\n", strlen(&arr+1));//存放数组地址的指针变量地址+1往后找,后\0未知是一个随机值 x-6
printf("%d\n", strlen(&arr[0]+1));//从第二个元素地址往后找,后\0未知是一个随机值 x-1
运算结果:
char arr[] = "abcdef";//将字符串放进数组,会将其后的\0一同放进数组
printf("%d\n", sizeof(arr));//整个数组的大小 7
printf("%d\n", sizeof(arr+0));//首元素地址 4
printf("%d\n", sizeof(*arr));//第一个元素的类型大小 1
printf("%d\n", sizeof(arr[1]));//第二个元素的类型大小 1
printf("%d\n", sizeof(&arr));//整个数组的地址 4
printf("%d\n", sizeof(&arr+1));//用于存放字符串地址的指针变量的下一个地址 4
printf("%d\n", sizeof(&arr[0]+1));//第二个元素的地址 4
printf("%d\n", strlen(arr));//首元素地址往后找到\0时的元素个数,不包括\0 6
printf("%d\n", strlen(arr+0));//首元素地址往后找到\0时的元素个数,不包括\0 6
printf("%d\n", strlen(*arr));//第一个元素 参数错误
printf("%d\n", strlen(arr[1]));//第二个元素 参数错误
printf("%d\n", strlen(&arr));//存放数组地址的指针变量地址往后找(数值上等于首元素地址) 6
printf("%d\n", strlen(&arr+1));//存放数组地址的指针变量地址+1往后找,后\0未知是一个随机值
printf("%d\n", strlen(&arr[0]+1));//从第二个元素地址往后找,找到\0时的元素个数,不包括\0 5
运算结果:
char *p = "abcdef";
printf("%d\n", sizeof(p));//字符串的地址,数组传参传的是首元素地址 4
printf("%d\n", sizeof(p+1));//第二个元素的地址 4
printf("%d\n", sizeof(*p));//第一个元素的类型大小 1
printf("%d\n", sizeof(p[0]));//第一个元素的类型大小 1
printf("%d\n", sizeof(&p)); //用于存放字符串地址的指针变量的地址 4
printf("%d\n", sizeof(&p+1));//用于存放字符串地址的指针变量的地址+1 4
printf("%d\n", sizeof(&p[0]+1));//第二个元素的地址 4
printf("%d\n", strlen(p));//首元素地往后找,遇\0时的元素个数 6
printf("%d\n", strlen(p+1));//第二个元素地址往后找,遇\0时的元素个数 5
printf("%d\n", strlen(*p));//表示首元素,参数错误
printf("%d\n", strlen(p[0]));//表示首元素,参数错误
printf("%d\n", strlen(&p));//存放字符串地址的指针变量地址往后找,后\0未知是一个随机值
printf("%d\n", strlen(&p+1));//存放字符串地址的指针变量地址+1往后找,后\0未知是一个随机值,这个随机值和上面的随机值无联系
printf("%d\n", strlen(&p[0]+1));//从第二个元素地址往后找,找到\0时的元素个数,不包括\0 5
运算结果:
int a[3][4] = {0};//
printf("%d\n",sizeof(a));//整个数组的大小 48
printf("%d\n",sizeof(a[0][0]));//第一行第一个元素的大小 4
printf("%d\n",sizeof(a[0]));//第一行的大小 16
printf("%d\n",sizeof(a[0]+1));//第一行,第二个元素的地址 4
printf("%d\n",sizeof(a+1)); //第二行的地址 4
printf("%d\n",sizeof(&a[0]+1));//第二行的地址 4
printf("%d\n",sizeof(*a)); //对第一行的地址解引用,得到第一行元素 16
printf("%d\n",sizeof(a[3])); //类型等同于:a[1] a[2]大小为:16,因为siezof后面表达式不参与运算,只计算类型大小,与sizeof(int)道理相同
运算结果: