数组名的本质

数组名本质上是一个常量指针

1.一维数组

int b[10];

在数组表达式中,数组名的值是一个指针常量,指向数组第一个元素的地址。它的类型取决于数组元素的类型。

int *b;

b++;

可以通过编译。

int a[10];

a++;

不能通过编译。因为a是一个指针常量,它指向的地址是固定的。


指针和数组的区别:数组名在表达式中使用的时候,编译器才会产生一个指针常量。但当数组名作为sizeof操作符的操作数的时候,不能指针常量看待,此时sizeof返回的是整个数组的长度,而不是指针的长度。当数组名作为&操作符的操作数的时候,返回的是一个指向数组的指针,而不是指向某个数组元素的指针常量。

声明一个数组时,编译器根据声明所指定的元素数量为数组分配内存空间,然后再创建数组名,指向这段空间的起始位置。声明一个指针变量的时候,编译器只为指针本身分配内存空间,指针并未初始化指向任何现有的内存空间。

------------------------------------------------------------------------------------------------------

一维数组作为函数参数

void fun(int a[]);void fun(int* a);

2.二维数组

int a[2][3];

一维数组的数组名是一个指针常量,它的类型是指向元素类型的指针,它指向数组的第一个元素。同理,二维数组的数组名也是指向第一个元素,只不过第一个元素是一个数组。a[2][3]是一个一维数组,包含了2个元素,只是每个元素都是包含了3个元素的数组。

3.定义数组指针

<1.

typedef int(array)[10];

array arr;//定义一个数组 int arr[10]

<2.

typedef int(*array)[10];

int arr[10];

array parr=&arr;//定义了一个数组指针parr,并指向数组arr

<3.

int arr[10];

int (*parr)[10]=&arr;

4.栈区与堆区指针数组

栈区指针数组

void sort(char** arr,int len)

{

int i,j;

char* tmp;

for(i=0;i

{

for(j=len-1;j>i;j--)

{

if(strcmp(arr[j-1],arr[j])>0)

{

tmp=arr[j-1];

arr[j-1]=arr[j];

arr[j]=tmp;

}

}

}

}

堆区指针数组

void heap(int n)

{

char **p=(char**)malloc(sizeof(char*)*n);

int i;

for(i=0;i为每一个指针分配内存

{

p[i]=(char*)malloc(sizeof(char)*10);

sprintf(p[i],”%d haha”,i+1);

}

for(i=0;i

{

printf(“%s\n”,p[i]);

}

for(i=0;i先释放二级指针,再释放一级指针

{

free(p[i]);

 

}

free(p);

}

int main()

{

char* p[]={“aaa”,”ccc”,”bbb”};

int len=sizeof(p)/sizeof(char*);

sort(p,len);

heap(5);

return 0;

}

5.二维数组作为函数参数

void fun1(int arr[2][3]);

void fun2(int arr[][3]);

void fun3(int (*arr)[3]);


你可能感兴趣的:(c语言)