数组的基本概念
• 元素类型角度:数组是相同类型的变量的有序集合
• 内存角度:连续的一大片内存空间
数组名
数组首元素的地址和数组地址是两个不同的概念
数组名代表数组首元素的地址,它是个常量。
变量本质是内存空间的别名,一定义数组,就分配内存,内存就固定了。所以数组名起名以后就不能被修改了。
数组首元素的地址和数组的地址值相等
int a[10];
printf("得到整个数组的地址a: %d \n", &a);
printf("数组的首元素的地址a: %d \n", a);
怎么样表达int a[10]这种数据类型?
数组类型
数组的类型由元素类型和数组大小共同决定
int array[5] 的类型为 int[5];
#include <stdio.h>
/*
typedef int(MYINT5)[5];
typedef float(MYFLOAT10)[10];
数组定义:
MYINT5 iArray; 等价于 int iArray[5];
MYFLOAT10 fArray; 等价于 float fArray[10];
*/
/*定义 数组类型,并用数组类型定义变量*/
int main(void)
{
typedef int(MYINT5)[5];
int i = 0;
MYINT5 array;
for (i=0; i<5; i++)
{
array[i] = i;
}
for (i=0; i<5; i++)
{
printf("%d ", array[i]);
}
return 0;
}
指针数组
char *point_array[4];
指针数组,是一个数组, 里面的每一个元素都是一个指针。(多个指针)
数组指针
int (*array_point)[4];
是一个指针,指向一个数组。(一个指针)
案例:
#include <stdio.h>
int main(int)
{
int a[3][5], i=0, j=0;
// a 多维数组名 代表?
printf("a %d , a+1:%d ", a, a+1);
//a+1的步长 是20个字节 5*4
printf("&a %d , &a+1:%d ", &a, &a+1);
//&+1的步长 是5*4*3 = 60
//多维数组名的本质就是一个指向第一个维度的数组的指针
//步长为第一个维度的数据类型大小
//定义一个指向数组的指针变量
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+i) 代表是整个第i行的地址 二级指针
// *(a+i) 代表 1级指针 第i行首元素的地址
// *(a+i) + j ===> & (a[i][j])
//*( *(a+i) + j) ===> a[i][j]元素的值
return 0;
}
多维数组的表现形式
#include <stdio.h>
void printArray01(int a[3][5])
{
int i, j;
for (i=0; i<3; i++)
{
for (j=0; j<5; j++)
{
printf("%d ", a[i][j]);
}
}
}
void printArray02(int a[][5])
{
int i, j;
for (i=0; i<3; i++)
{
for (j=0; j<5; j++)
{
printf("%d ", a[i][j]);
}
}
}
void printArray03( int (*b)[5])
{
int i, j;
for (i=0; i<3; i++)
{
for (j=0; j<5; j++)
{
printf("%d ", b[i][j]);
}
}
}
int main(void)
{
int a[3][5], i=0, j=0;
int tmp = 1;
for (i=0; i<3; i++)
{
for (j=0; j<5; j++)
{
a[i][j] = tmp++;
}
}
printArray03(a);
return 0;
}
形参退化成指针的原因
原因1:高效
原因2:C语言处理a[n]的时候,它没有办法知道n是几,它只知道&n[0]是多少,它的值作为参数传递进去了,虽然c语言可以做到直接int fun(char a[20]),然后函数能得到20这个数字,但是,C没有这么做。