1.一维数组的创建和初始化
(1)数组的创建
数组是一组相同类型元素的集合。
创建方式:
type arr_name [const];
//type:数组的元素类型
//const:常量表达式,指定数组的大小
不能分配大小为0的数组。
(2)数组的初始化
int arr1[3] = {1, 2, 3};
char arr2[] = {'a','b','c'};//三个元素
char arr2[] = "abc";//四个元素(\0)
char *p = "abc";//把a的地址放入到p
char arr1[] = {'a', 'b', 'c'};
char arr2[] = "abc";
printf("%s\n", arr1);//abc+乱码
printf("%s\n", arr2);//abc(\0)
int main()
{
char *p1 = "abcdef";
char *p2 = "abcdef";
if(p1==p2)
printf("haha\n");
return 0;
}
//输出haha。
//abcdef是常量字符串,不能更改,所以只存一份。
int main()
{
char arr1[] = "abcdef";
char arr2[] = "abcdef";
if(arr1==arr2)
printf("haha\n");
return 0;
}
//不输出
//数组可以更改,arr1和arr2不同。
2.一维数组的使用
数组是使用下标来访问的,下标从0开始。
数组的大小可以通过计算得到。(sizeof)
3.一维数组在内存中的存储
#include<stdio.h>
int main()
{
int arr[10] = { 0 };
int i = 0;
for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
printf("&arr[%d] = %p\n", i, &arr[i]);
}
return 0;
}
/*输出:
&arr[0] = 00EFFE80
&arr[1] = 00EFFE84
&arr[2] = 00EFFE88
&arr[3] = 00EFFE8C
&arr[4] = 00EFFE90
&arr[5] = 00EFFE94
&arr[6] = 00EFFE98
&arr[7] = 00EFFE9C
&arr[8] = 00EFFEA0
&arr[9] = 00EFFEA4
*/
//一个内存单元是4个字节
数组在内存中是连续存放的。随着数组下标的增长,元素的地址也递增。
4.一维数组的指针访问
#include<stdio.h>
int main()
{
int arr[10] = { 0 };
int i = 0;
int *p = arr;
int sz = sizeof(arr) / sizeof(arr[0]);
for (i = 0; i < sz; i++)
{
*(arr + i) = i;
arr[i] = i;
*(p + i) = i;
*(i + p) = i;
p[i] = i;
i[p] = i;
//以上6个语句等价
}
for (i = 0; i < sz; i++)
printf("%d ", arr[i]);
printf("\n");
return 0;
}
//输出:
0 1 2 3 4 5 6 7 8 9
内存中的一个内存单元(一个字节)对应一个地址。
在32位平台上指针的大小是4个字节。64位平台是8个字节。
5.二维数组的创建和初始化
int arr1[3][4] = {1,2,3,4,5,6};
int arr2[3][4] = {{1,2},{3,4,5},{6}};
int arr3[][4] = {{1,2},{3,4,5},{6}};
6.二维数组的使用
int main()
{
int arr[3][5] = { 0 };
int i = 0;
int j = 0;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 5; j++)
{
arr[i][j] = i * 5 + j + 1;
}
}
for (i = 0; i < 3; i++)
{
for (j = 0; j < 5; j++)
{
printf("%d\t", arr[i][j]);
}
printf("\n");
}
return 0;
}
//输出:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
7.二维数组在内存中的存储
int main()
{
int arr[3][5] = { 0 };
int i = 0;
int j = 0;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 5; j++)
{
printf("$arr[%d][%d] = %p\n", i, j, &arr[i][j]);
}
}
return 0;
}
//输出:
$arr[0][0] = 0053FE00
$arr[0][1] = 0053FE04
$arr[0][2] = 0053FE08
$arr[0][3] = 0053FE0C
$arr[0][4] = 0053FE10
$arr[1][0] = 0053FE14
$arr[1][1] = 0053FE18
$arr[1][2] = 0053FE1C
$arr[1][3] = 0053FE20
$arr[1][4] = 0053FE24
$arr[2][0] = 0053FE28
$arr[2][1] = 0053FE2C
$arr[2][2] = 0053FE30
$arr[2][3] = 0053FE34
$arr[2][4] = 0053FE38
二维数组在内存中连续存储。所以列元素的个数必须给出。
8.二维数组的指针访问
int main()
{
int arr[3][5] = { 0 };
int *p = &arr[0][0];
//int *p = arr;//出错。arr指arr[0]的地址,不是arr[0][0]的地址。
int i = 0;
for (i = 0; i < 15; i++)
{
*(p + i) = i + 1;
}
for (i = 0; i < 3; i++)
{
for (int j = 0; j < 5; j++)
{
printf("%d ", arr[i][j]);
}
}
return 0;
}
//输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
int main()
{
int num = 10;
int *p = #
char *pc = #
printf("%p\n", p);
printf("%p\n", p+1);
printf("%p\n", pc);
printf("%p\n", pc+1);
return 0;
}
//输出:
005FF830
005FF834
005FF830
005FF831
//指针类型的差异
int main()
{
int arr[10] = { 0 };
printf("&arr[0] = %p\n", &arr[0]);
printf("&arr[0] + 1 = %p\n", &arr[0]+1);
printf("arr = %p\n", arr);
printf("arr + 1 = %p\n", arr+1);
printf("&arr = %p\n", &arr);
printf("&arr + 1 = %p\n", &arr+1);
return 0;
}
//输出:
&arr[0] = 00AFFDA8
&arr[0] + 1 = 00AFFDAC
arr = 00AFFDA8
arr + 1 = 00AFFDAC
&arr = 00AFFDA8
&arr + 1 = 00AFFDD0//差40
9.有关数组的运算
int main()
{
int a[] = { 1,2,3,4 };
//数组名单独放在sizeof内部,数组名表示整个数组
//&数组名,数组名表示整个数组
//除此之外,所有的数组名抖表示首元素地址
printf("%d\n", sizeof(a));//16
printf("%d\n", sizeof(a + 0));//4
printf("%d\n", sizeof(*a));//4
printf("%d\n", sizeof(a + 1));//4
printf("%d\n", sizeof(a[1]));//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));//随机值(没有结束标志)
printf("%d\n", strlen(arr + 0));//随机值
printf("%d\n", strlen(*arr));//error
printf("%d\n", strlen(arr[1]));//error
printf("%d\n", strlen(&arr));//随机值
printf("%d\n", strlen(&arr + 1));//随机值
printf("%d\n", strlen(&arr[0] + 1));//随机值
char arr[] = "abcdef";
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));//6
printf("%d\n", strlen(arr + 0));//6
printf("%d\n", strlen(*arr));//error
printf("%d\n", strlen(arr[1]));//error
printf("%d\n", strlen(&arr));//6
printf("%d\n", strlen(&arr + 1));//随机值
printf("%d\n", strlen(&arr[0] + 1));//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));//4
printf("%d\n", sizeof(&p[0] + 1));//4
printf("%d\n", strlen(p));//6
printf("%d\n", strlen(p + 1));//5
printf("%d\n", strlen(*p));//error
printf("%d\n", strlen(p[0]));//error
printf("%d\n", strlen(&p));//随机值
printf("%d\n", strlen(&p + 1));//随机值
printf("%d\n", strlen(&p[0] + 1));//5
int a[3][4] = {0};
printf("%d\n", sizeof(a));//12*4
printf("%d\n", sizeof(a[0][0]));//4
printf("%d\n", sizeof(a[0]));//4*4
printf("%d\n", sizeof(a[0] + 1));//4//第一行第二个元素的地址
printf("%d\n", sizeof(a + 1));//16//第二行的地址
printf("%d\n", sizeof(&a[0] + 1));//4//第二行的地址
printf("%d\n", sizeof(*a));//16
printf("%d\n", sizeof(a[3]));//16
//sizeof括号内不参与运算,只看a[3]的类型
return 0;
}
10.数组作为函数参数
int sort(int arr[])
{}
//实际上传的是地址,不是数组。