c ++指针在这段代码中做了什么

时间:2015-02-09 11:06:06

标签: c++ pointers function-pointers

#include <cstdlib>
#include <iostream>

using namespace std;

void f(int k[0]){ --k[1]; }
void g(int *k){(*(--k))++;}
void h(int k[1]){--k;}

int main(){
    int k[]={1,2,3,4};
    f(k+2);
    g(k+2);
    h(k+2);
    for (int i = 1; i < 4; i++)
        cout << k[i];
}

正确的输出是333,但我认为它是334。 我不明白函数f在指令--k[1]中究竟发生了什么。如果代码是k[0]--,我可以同意正确的输出。有什么区别? 感谢

5 个答案:

答案 0 :(得分:1)

--k[1]递减k[1]的值,给定f(k+2)表示f() - 本地k指向来电者(即main() 's)k[2],并且1和2索引添加,你实际上是将调用者的k[3]从4减少到3。

k[0]--会在*k处递减变量,f在调用者的上下文中将k[2]称为f

理解此代码的重要见解是:

  • 所有功能ghint最终都会获得指向k的指针,他们的概念“k”是完全独立于调用者的int概念,特别是 - 它在调用者的k数组中进一步偏移2 --k[1]

  • operator precedence:具体而言,在{{1}} 数组下标之后,应用前缀减量。

那就是说,paxdiablo肯定有一点......; - )。

答案 1 :(得分:1)

首先,所有三个函数都具有完全相同的签名。如果写完它会不那么令人困惑:

void f(int* pi){ --pi[1]; }
void g(int* pi){(*(--pi))++;}
void h(int* pi){--pi;}

(我已经更改了参数的名称以避免在下面的讨论中出现歧义。)

此外,当然:a[b]根据定义为*(a + b)k上的任何操作都会将其从int[4]转换为int*,指向第一个元素。

所以我们得到以下结果:

f( k + 2 );
//  In f, pi is k + 2, so `pi[1]` is *(k + 3).
//  After f, k = { 1, 2, 3, 3 }
g( k + 2 );
//  In g, pi starts out as k + 2; it is then decrementd to give k + 1
//  After g, k = { 1, 3, 3, 3 }
h( k + 2 );
//  In h, pi is k + 2.  A local copy of k + 2, so h doesn't change
//  k at all.

结果是在{4}操作之后k{ 1, 3, 3, 3 }

答案 2 :(得分:1)

稍微更改代码,您可以查看每个步骤的操作:

#include <cstdlib>
#include <iostream>
using namespace std;

int *globk;
void dumpk(int *pk) {
    cout << "Array:";
    for (int i = 0; i < 4; i++)
        cout << ' ' << globk[i];
    cout << ", k at index " << (pk-globk) << '\n';
}

void f(int k[0]) { dumpk(k);    --k[1];  dumpk(k); }
void g(int *k)   { dumpk(k); (*(--k))++; dumpk(k); }
void h(int k[1]) { dumpk(k);    --k;     dumpk(k); }

int main(){
    int k[]={1,2,3,4};
    globk = k;  // save for detecting where k is

    f(k+2);
    g(k+2);
    h(k+2);

    // slightly prettier output.

    for (int i = 1; i < 4; i++)
        cout << k[i] << ' ';
    cout << '\n';
}

其输出显示了每个步骤的作用:

Array: 1 2 3 4, k at index 2
Array: 1 2 3 3, k at index 2
--k[1];         // -- array VALUE at INDEX 3 (2+1) down to 3

Array: 1 2 3 3, k at index 2
Array: 1 3 3 3, k at index 1
(*(--k))++;     // -- POINTER to [1], then ++ that VALUE up to 3

Array: 1 3 3 3, k at index 2
Array: 1 3 3 3, k at index 1
--k;            // Simply -- POINTER with no change to any VALUE

答案 3 :(得分:0)

此代码的作用是:

  1. 将从k[]的第3个元素开始的数组传递给ff采用一维数组并减少其第二个元素(在这种情况下,它将为k[4],它将其值4更改为3)。

  2. k[]中第3个元素的指针传递给gg获取一个指向整数或数组的指针,并首先减小指针的值(现在成为指向k[]的第二个元素的指针),然后增加指向的值,从而改变指针的值2至3。

  3. 将从k[]的第3个元素开始的数组传递给h。 ``h接收一维数组并减少指向数组的指针(不是它指向的值),因此不会修改指向数组的值。

答案 4 :(得分:0)

f和g正在修改值,而h正在修改地址:

f(int k[0]){ --k[1]; }

f取一个参数,一个int数组;在这种情况下,k [1]与k ++相同;该函数递减位于下一个地址的元素的值与作为参数传递的元素的值。所以它在你的主体中递减了k [3]。

g是相对直接的,我认为你想出来了。

h类似于f

h(int k[1]){--k;}

h将一个int数组作为输入,并递减作为参数传递的地址。

希望这有帮助