1,数组指针 和 指针数组
数组指针:
本质是指针,指向的是一维数组,如:int (*p)[20] ==>指向的是20个元素的一维数组,当然这里只是申请了指针,还没有为该指针分配可操作的空间。
首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长也 就 是说执 行p+1时,p要跨过n个整型数据的长度。
数组指针也叫行指针
指针数组:
本质是数组,其中的数组元素全是一维为指针。如:int *p[10] ==》其中的10个元素全是指针类型,当然这里只是申请了10指针,还没有为这些指针分配可操作的空间。
理解:
根据优先级: ( ) > [] > *,判断本质是数组还是指针
2,数组指针与malloc
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int (*p)[2] = NULL;
int i = 0 , j = 0;
p =( int (*)[2])malloc(2*3*sizeof(int));
for(i = 0; i < 2 ; i++)
{
for(j = 0 ; j < 3; j++)
{
p[i][j]= j+3;
}
}
for(i = 0; i < 2 ; i++)
{
for(j = 0 ; j < 3; j++)
{
//p[i][j]= j+3;
printf("p[%d][%d]= %d\n", i,j,p[i][j]);
}
}
printf("&p[0][2] = %x,&p[1][0] = %x \n",p[0][2],p[1][0]);
printf("&p[0][2] = %x,&p[1][0] = %x \n",&p[0][2],&p[1][0]);
free(p);
free(p[0]);
}
运行结果:
1,为什么p[0][2]的值不是5?
因为数组申请在内存中表现形式是线性的,p[0][2]相当于超了第一个数组的一格,但是访问的确是下一个数组的第一个元素,从p[0][2]和p[1][0]的地址相同是可以按照上面去理解的。也就是说第一for中,对p[0][2]复制为3时,在下一次循环中被p[1][0]=3 覆盖了,因为他们分配的地址是一样的。
所以:
为数组指针malloc空间时,不能单纯的把malloc申请的空间看成一个一个盒子,强转了后也不要随便去操作,如上: 我们malloc 了6个盒子,强转为数组指针--指向含2个元素的一维数组,此时这几个盒子已经按照3(行)*2(列)排列了,当然在内存是线性的。所以当我们去访问p[0][2] 时,其实就是访问了p[1][0]这个元素,从上面的赋值打印,地址值 都能看出来。注:因为p[0][2]的值被p[1][0]覆盖了,p[0][2]原值应该是5,在第二次循环中被覆盖了。
所以准确的赋值操作应该是如下循环:
for(i = 0; i < 3 ; i++)
{
for(j = 0 ; j < 2; j++)
{
p[i][j]= j+3;
}
}
总结:
malloc 申请的空间不可以理解为单纯的盒子(空间)--我们可以随便操作,应该按照强转后的类型,去准确的操作其中的元素, 不然可能造成元素值的覆盖或段错误。
释放空间时,因为是整体分配的空间,所以可以直接free(p) 或 free(p[0]) (因为首地址是一样的)。但不能free(p[0])再去free(p[1]),对一个空间free两次会段错误。
上面的代码使用malloc整体为数组指针分配的空间,所以是不是也可以单独为每一个指针分配空间?
但是有一个问题是我不知道具体需要多少个指针来指向这块空间,似乎可以这样分配:
int (*p)[2] = NULL;
p[0]=(int *)malloc( 2*sizeof(int));
p[1]=(int *)malloc( 2*sizeof(int));
p[2]=(int *)malloc( 2*sizeof(int));
p[3]=(int *)malloc( 2*sizeof(int));
...
p[n]=(int *)malloc( 2*sizeof(int));
待我实际验证》》》
不行,编译报错,好像是类型错误。
3,指针数组 和 malloc
//指针数组 mallloc
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int *p[2] = { NULL, NULL}; //int *p[2] = NULL; ->编译报错
int i , j;
//p = (int *[2])malloc(2*10*sizeof(int));//为数组指针分配空间
p[0] = (int *)malloc(10*sizeof(int));//为数组指针分配空间
p[1] = (int *)malloc(10*sizeof(int));//为数组指针分配空间
//综上:指针数组需要单独的对其中的指针分配空间,不能整体分配。
for(i = 0; i < 2 ; i++)
{
for(j = 0 ; j < 10; j++)
{
p[i][j]= j+5;
}
}
for(i = 0; i < 2 ; i++)
{
for(j = 0 ; j < 10; j++)
{
p[i][j]= j+5;
printf("p[%d][%d] = %d\n" ,i , j , p[i][j] );
}
}
printf("&p[0][9] = %x, &p[1][0] = %x", &p[0][9] , &p[1][0]);
printf("&p[0][9] = %x, &p[0][10] = %x,&p[1][0] = %x\n", &p[0][9], &p[0][10], &p[1][0]);
printf("p[0][9] = %d, p[0][10] = %d,p[1][0] = %d\n", p[0][9], p[0][10], p[1][0]);
//从打印的中看出,p[0]与p[1]不是连续分配的,之间地址不连续,当然内部是连续的。
free(p[0]);
free(p[1]);
}
运行:
综上:
为指针数组,初始化时,应该 int *p[2]={ NULL,NULL};
p[0] = (int *)malloc( 2*10*sizeof(int));
p[1] = (int *)malloc( 2*10*sizeof(int));
即:为每一个指针单独去malloc分配空间。p[0]与p[1](指针与指针之间)不是连续的地址。 同时释放也需要单独去free。