《Expert C Programming》中花了两篇写了数组与指针,这里将其中的一个图记录一下,也算是平时编程稍不注意就会产生bug的地方。
不同点:
1.声明的时候,如extern char a[],不能改写成指针的形式;
2.定义的时候,如char a[10],不能改写成指针的形式;
相同点:
1.函数的参数,可以是func(char a[]),也可以是func(char * a),因为数组名被编译器当作指向该数组第一个元素的指针;
2.表达式中,可以是c = a[i]; 也可以是 c = *(a + i);数组的下标总是与指针的偏移量相同。
如果你喜欢数组的下标从1到N,可以传入数组前面的一个位置的地址a[-1],但是这种方法与标准不兼容,很容易引起误会和bug,也有可能引起未定义的行为。
下面可以看一则多维数组和指针的表示:
int i, j, k;
int n = 0;
int ap[2][3][4];
for(i = 0; i < 2; i++)
{
for(j = 0; j < 3; j++)
{
for(k = 0; k < 4; k++)
{
ap[i][j][k] = n++;
}
}
}
int (*r)[4] = ap[0];
for(j = 0; j < 3; j++)
{
for(k = 0; k < 4; k++)
{
printf("%d, %d\t", *(*(r + j) + k), r[j][k]);
}
printf("\n");
}
int *p;
for(j = 0;j < 3; j++, r)
{
p = *r++;
for(k = 0; k < 4; k++)
{
printf("%d\t", *(p + k));
}
printf("\n");
}
还有一点,在C语言中,不能向函数传递一个普通的多维数组,如下:
void func(int a[][2][3]);
下面的可以调用:
int a[2][2][3]; func(a);
int a[99][2][3]; func(a);
但下面的不行:
int a[2][3][3]; func(a);
int a[99][8][8]; func(a);
因为传递一个多维数组,必须提供除了最左边一维以外的所有维的长度,这样就限制了把实参设置为除了最左边一维外所有维都必须和形参相匹配的数组。
多维数组的初始化:
int r1[] = {1, 2, 3, 4, 5, -1}; // -1 是º行结束的标识
int r2[] = {6, 7, -1};
int r3[] = {8, 9, 10, -1};
int *w[] = {
// 无法编译成功
/*
{1, 2, 3, 4, 5},
{6, 7},
{8, 9, 10}
*/
r1,
r2,
r3
};
for(i = 0; i < 3; i++)
{
for(j = 0; j < sizeof((w + i)); j++)
{
printf("%d\t", *(*(w + i) + j));
}
printf("\n");
}
使用指针从函数返回一个数组,想必这个应该很少用到吧
//paf是一个函数,指向一个包含20个int元素的数组的指针
int (*paf())[20]
{
int (*pear)[20];
pear = (int (*)[20])malloc(20 * sizeof(int));
return pear;
}
int mian()
{
int (*pa)[20] = paf();
if(pa)
{
for(i = 0; i < 20; i++)
{
(*pa)[i] = i;
printf("%d, %d\t", (*pa)[i], **pa + i);
}
printf("\n");
}
return 0;
}