数组名的技术盲点
- 数组首元素的地址和数组地址是两个不同的概念
 - 数组名代表数组首元素的地址,它是个常量。
- 解释如下:变量本质是内存空间的别名,一定义数组,就分配内存,内存就固定了。所以数组名起名以后就不能被修改了。
 
 - 数组首元素的地址和数组的地址值相等
 - 怎么样得到整个一维数组的地址?
 
#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdlib.h>#include<string.h>void main(){int a[] = { 1, 2};int b[100] = { 1, 3 };int c[200] = { 0 }; //编译时 就已经确定 所有的值 为零memset(c, 0, sizeof(c)); //显示的 重置内存块// 对一维数组C规定:// c 是数组首元素的地址 c+1 步长 4个字节// &c 是整个数组的地址 &c+1 步长 200*4system("pause");return;}
C语言规定:
Int a[10];printf("得到整个数组的地址a: %d \n", &a); // 整个数组的地址printf("数组的首元素的地址a: %d \n", a); // 首元素的地址
怎么样表达int a[10]这种数据类型那?
数组类型、数组指针类型、数组指针类型变量
数组类型
- 1数据类型分为基础、非基础,思考角度应该发生变化
 - 2 C语言中的数组有自己特定的类型
- 数组的类型由元素类型和数组大小共同决定
 - 例:int array[5]的类型为int[5]
 
 
数组定义:
typedef int(MYINT5)[5]; //inttypedef float(MYFLOAT10)[10];MYINT5i Array; int array[5];MYFLOAT10fArray
定义数组类型,并用数组类型定义变量
void main(){typedef int(MyArrayType)[5]; // 定义了一个数据类型 数组数据类型int i = 0;MyArrayType lessons;for (i = 0; i < 5; i++) {lessons[i] = i + 1;}printf("lessons:%d lessons+1:%d\n", lessons, lessons + 1); // lessons : 4193968 lessons + 1 : 4193972 步长4printf("&lessons:%d &lessons+1:%d\n", &lessons, &lessons + 1); // &lessons : 4193968 &lessons + 1 : 4193988 步长20system("pause");return;}
数组指针类型
- 定义数组指针变量的方法1:用数组类型 加*
 
void main(){char *MyArray[] = { "111","2222","3333" }; // 指针 数组typedef int(MyArrayType)[5]; // 定义了一个数据类型 数组数据类型int i = 0;MyArrayType lessons; // 数据类型 定义变量MyArrayType *pLessons; // 数据类型 定义一个指针变量 这个指针变量 指向一个数组{int a;int *p = NULL;p = &a;}{int lessons2[5];// 可以通过指针变量pLessons来操作lessons2的内存空间pLessons = &lessons2; // pLessons = &lessons;for (i = 0; i < 5; i++) {// lessons2[i] = i + 1;(*pLessons)[i] = i + 1;}for (i = 0; i < 5; i++) {printf("%d ", (*pLessons)[i]); // 1 2 3 4 5}}system("pause");return;}
- 定义数组指针变量的方法2
 
void main(){typedef int (*MyArrayType)[5]; // 定义了一个数组指针类型MyArrayType pLessons; // 告诉编译器 分配一个指针变量int c[5];int i = 0;pLessons = &c;for (i = 0; i < 5; i++) {(*pLessons)[i] = i + 1;}for (i = 0; i < 5; i++) {printf("%d ", (*pLessons)[i]); // 1 2 3 4 5}system("pause");return;}
- 定义数组指针变量的方法3
- 前面两种方法 通过类型定义 比较麻烦
 - 直接定义 int (*pLessons)[5]
 
 
void main(){int c[5];int i = 0;int (*pLessons)[5]; // 直接定义了一个指向数组的 指针变量pLessons = &c;for (i = 0; i < 5; i++) {(*pLessons)[i] = i + 1;}for (i = 0; i < 5; i++) {printf("%d ", (*pLessons)[i]); // 1 2 3 4 5}system("pause");return;}
多维数组的本质
#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdlib.h>#include<string.h>void printfArr1(int a[3][5]){int i, j, tmp = 0;for (i = 0; i < 3; i++){for (j = 0; j < 5; j++){printf("%d ", a[i][j]);}}return;}void printfArr2(int a[][5]){int i, j, tmp = 0;for (i = 0; i < 3; i++){for (j = 0; j < 5; j++){printf("%d ", a[i][j]);}}return;}//多维数组做函数参数的推演void printfArr3(int(*b)[5]){int i, j, tmp = 0;for (i = 0; i < 3; i++){for (j = 0; j < 5; j++){printf("%d ", b[i][j]);}}return;}void main(){int a[3][5];int i = 0, j = 0, tmp = 1;for (i = 0; i < 3; i++){for (j = 0; j < 5; j++){a[i][j] = tmp++;}}printf("\n-------------------\n");printfArr3(a);printf("\n-------------------\n");for (i = 0; i < 3; i++){for (j = 0; j < 5; j++){printf("%d ,", a[i][j]);}}printf("\na:%d , a+1:%d\n ", a, a + 1);//a+1的步长是20个字节 5*4printf("&a:%d , &a+1:%d\n ", &a, &a + 1);{//定义一个指向数组的指针变量int(*pArray)[5];//告诉编译器 分配4个字的内存 32bit平台下pArray = a;for (i = 0; i < 3; i++){for (j = 0; j < 5; j++){printf("%d,", pArray[i][j]);}}}/*多维数组的本质 数组指针 ,步长 一维的长度(a) 代表是第0行的整个地址 (第一行的地址 和 第一行首元素的地址是重叠的。。。)(a+i) 代表是第i行的首地址 2级指针*(a+i) 代表 1级指针 第i行的首元素的地址*//*转化推演:*( *(a+i) + j) ===>a[i][j] 元素的值a[i][j] <===> *(*(a+i)+j)a[i] ===> a[0+i] ===>*(a+i) 0是占位符a[i][j]===a[0+i][j] ==> *(a+i)[j] ===>*(a+i)[0+j] ===>* ( *(a+i) + j)**/system("pause");return;}
