C语言的一个笔试题:指针与数组的问题

来源:互联网 发布:知乎市值 编辑:程序博客网 时间:2024/04/29 06:48

1.数组和指针

对于一维数组其实很好理解。

假设数组int A[n],

和int *p;

因为都知道数组名其实就可以表示数组的首地址

既p = A;

然后我们可以用指针来操作数组。

 *p = A[0];

*(p+1) = a[1];

然后去掉(),既*p+1=A[0]+1;因为*的优先级高于双目运算符+,所以是先取了数组第一个元素,然后+1;

*p++ 则是其实是两步操作,先取了p指向值,然后指针++;

其实按运算符优先级和操作顺序来说是这个表达式是这么结合起来的。

*和++的优先级处于同一个级别,都是从右往左结合。因此p先和++结合,*和p结合。

但是p++是要等整个表达是结束,p值才++。因此正确的描述应该这样的。

而对于前面说先取p指向值,然后指针++只是说表面上和逻辑是这么呈现的。

但是这和先取p指向值,然后p指向值++是完全不同概念。

这个的表达形式应该是这样(*p)++;

而*p++这样的表达是一般常用指针操作数组进行元素的遍历。


对于多维数组,就会有点复杂。

比如int A[n][n].

数组名此时数组名是数组A第一个元素的首地址。

但是会如果我们申明一个int *p指针,给p赋值为

p = A是有误的。p指向的是一个int类型变量的地址。

但是A是一个2维数组,A表示的首地址是指向是一个(指向int变量类型的指针),既指针指向的是

一个指针变量,也就是A的指向感觉是比p指向多了一级。

因此 这样表示 p = *A从类型来看是正确的。

如果将A[0]看成整体,*A就表示了A[0]的首地址,而我们知道A[0]中又有N个int类型的元素,同样如果我们在细分一下的话,就可得知,*A也就表示是A[0][0]元素的地址,那么对于获取A这个多维数组的第一个int元素

我们就可以这么表示了 **A,

因此我们取A[n][n]的第一个元素可以这么表示

A[0][0] = **A = *A[0];

那么如何遍历A中的元素。

*(*A+i); 0<=i <=n^2;

比如i取2,表达式的意思就是,*A取了A[0]中元素的首地址,然后偏移了两位,

就指向了A[0]中第三个元素A[0][2];

那么稍微改变下**A+i表示的是什么?

*的优先级高于双目+。那么实际上(**A)+i;

添上括号就很好理解了,一直做的是取了A[0][0]然后+i。

至此,我们还可以推测出一种情况

**(A+i),此刻A指针偏移了i位,事实上是从A[0]变成了A[0+i];


如果和一维数组一样用指针来操作数组元素遍历。

我尝试申请一个int *p用++自加来实现

int *p = A[0]后其实和一维数组操作是一样的。


tips;这边在提一个很重要的问题。

我们以一维数组举例

我们知道int *p = A;

然后可以用 p++来遍历数组。

那直接用A++不就也可以实现位置偏移嘛?

但是这是错误的,数组A确定后,A首地址是固定不变的,假设让我们操作了

A++,那么也就是说A数组首地址往后偏移了一位,那对于A来说,A已经不能表达

原来那个数组了。因为你地址偏移了,对于数组来说,你就少了一个元素存储空间,

因此,资料行也明确定义了不能直接拿数组来做指针++或是--,编译器也报错通不过。


以上是一个朋友去校招碰到的一个题目,多维数组用指针操作的问题~