#include <stdio.h> #include <stdlib.h> int getItem(int *a,int i,int j) { return *(a+i*3+j); } void add(int *p) { (*p)++; } int main() { int a[4][3]={{1,2,3},{4,5,6},{7,8,9},{12,13,14}}; int b=6; add(&b); printf("%d\n%d\n%d\n",*(*(a+2)+1),getItem(a,2,1),b); return 0; }
这是腾讯的一个笔试题,纠结了一段时间,终于想明白了。
上面getItem函数很容易写成 return *(*(a+i)+j);这是错误的,为什么呢?因为形参是 int *a;所以指针变量a赋值给a后,它变成了int型的指针,每次加1相当于内存地址中加4,所以要用return *(a+i*3+j);其实二维数组里面a和a[0]地址是一样的,但是性质不一样,a是数组指针的首地址,a[0]是第一行数据的首地址,*(a+1)=a[1];这个公式和一维数组一样。
如果还不懂,就看下面这个例子:
#include <stdio.h> #include <stdlib.h> int main() { int a[2][3]={{1,2,3},{4,5,6}}; int *p=a; int (*pp)[3]=a; printf("%d\n%d\n%d\n%d\n%d",a[1][1],*(a[0]+3+1),*(p+3+1),*(*(a+1)+1),*(*(pp+1)+1)); return 0; }
输出结果全是5,即a[1][1]的值。你都能看懂吗?对于指针变量p,相当于 int *p=(int *)a;强制转换一下。对于pp指针变量,则正好和a效果是一样的。
共勉。