<C> 数组

一.数组

1.定义:int arr[n]; //n为元素个数

2.数组的三种初始化方法:

①完全初始化:arr[10] = {0,1,2,3,4,5,6,7,8,9};

②不完全初始化:arr[10] = {0,1,2,3};

注:在不完全初始化中 至少赋1个的值 其余没有进行赋值的数为0

③int arr[] = {0,1,2,3};

3.数组的遍历:for循环输出arr[下标数字]

4.一般情况下 数组的名字→首元素的地址

*arr = 100会使数组的第一个值改变 但是当数组名与&和sizeof()结合使用的时候 代表的是整个数组

例如:

1 printf("%d\n",sizeof(arr));
2 printf("%d\n",sizeof(int [10]));

 以上两种输出方式的结果都是40

1 printf("%d\n",arr);
2 printf("%d\n",arr+1);

这两种输出方式的结果相差4

1 printf("%d\n",&arr);
2 printf("%d\n",&arr+1);

这两种输出方式的结果是相差40的

注:数组名是常量 是不能被更改的 下面附上两种错误的写法:arr = arr + 1;或arr++;

5.[]的访问原理:

数组名+下标 === 偏移量 + 间接引用(先偏移 后间接引用

即arr[0] === *(arr + 0) ……(以此类推)

特殊的是:当间接引用整个数组的地址是 那到的是首元素的地址 即&arr

例:我们想拿到数组中第二个元素的值 我们可以有一下几种不同的表示方法:

1 arr[1];
2 *(arr+1);
3 *(*&arr+1);
4 (&arr)[0][1];

再放一道典型的例题:

1 #include<stdio.h>
2 int main()
3 {
4     int arr[10] = {0,1,2,3,4,5,6,7,8,9};
5     printf("%d\n",(&arr)[1][-1]);
6 }

这个题输出的结果是9

(&arr)[1]完成后 指的是arr[10]后面的四十个字节 间接引用后 又变成一个int大小的 然后[-1] 指向元素9

(&arr)[1][-1]也可以表示为*(*((&arr)+1)-1)

二.指针数组

1.定义方法:int* arr[5] = {&a,&b,&c,&d,&e};

2.输出数组中的值的两种方法:

1 printf("%d\n",*arr[i]);
2 printf("%d\n",*(*(arr+i)));

三.数组指(是指针)

1.定义方法:int (* p) [10] = &arr;

2.输出方式:

①printf("%d\n",*(*p+i)); //*p === *&arr

②printf("%d\n",p[0][i]);

总结:arr是int*类型 &arr是int* [10]类型

例如:char* arr[5]→(的指针为)char* (* p) [5]

易错点:

1 int* p1,p2;

这行定义中p1是int*类型的 是一个指针 但p2是int型的 是一个变量

四.二维数组

1.定义方法:int arr[2][5];

2.初始化方法:

①完全初始化:int arr[2][5] = {0,1,2,3,4,5,6,7,8,9};

②不完全初始化:int arr[2][5] = {0,1,2,3}; //把值给前面的 后面的为0

③int arr[2][5] = {{0,1,2,3,4},{5,6,7,8,9}};

④int arr[][5] = {0,1,2,3,4,5,6,7,8,9};

3.访问:arr[0][3] = 300;

上面的语句中 arr是二维数组的名 第一个[]表示偏移0个 间接引用 到0的位置 第二个[]表示偏移3个 间接引用 拿到3

注:数组的存储是连续的 arr[1][5] === arr[2][0]

放一道简单的写过的一个类型题:

1 #include<stdio.h>
2 int main()
3 {
4     int arr[2][5] = {0,1,2,3,4,5,6,7,8,9};
5     printf("%d\n",(&arr)[1][1][-8]);
6 }

输出结果为7 这个题上面写过类型题 在这里就不作过多的解释了

 

posted @ 2018-04-01 15:16  Aaaaaalei  阅读(130)  评论(0编辑  收藏  举报