c++ 指针在此代码中的作用
what c++ pointers do in this code
#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
。
我不明白指令 --k[1]
在函数 f 中到底发生了什么。如果代码是 k[0]--
,我可以同意正确的输出。有什么不同?
谢谢
--k[1]
递减 k[1]
处的值,给定 f(k+2)
意味着 f()
-local k
指向调用者的(即 main()
's) k[2]
,加上 1 和 2 索引,您实际上是在将调用者的 k[3]
从 4 减少到 3.
k[0]--
会递减 *k
处的变量,对于 f
,在调用者的上下文中会被称为 k[2]
。
理解这段代码的重要见解是:
所有函数 f
、g
和 h
最终得到一个指向 int
的指针,以及它们的概念“k
" 完全独立于调用者的 k
概念,具体来说 - 它在调用者的 k
数组中偏移 2 int
s,
operator precedence:具体来说,在--k[1]
.
[=48中的数组下标后应用前缀递减 =]
话虽如此,paxdiablo 确实有道理……;-)。
这段代码的作用是:
将一个数组从 k[]
中的第 3 个元素开始传递到 f
。 f
采用一维数组并减少其第二个元素(在本例中为 k[4]
,这会将其值 4 更改为 3)。
将k[]
中第3个元素的指针传递给g
。 g
接受一个指向整数或数组的指针,首先减少指针的值(现在变成指向 k[]
的第二个元素的指针)然后增加指向的值,将其从2 到 3.
将一个从 k[]
中的第 3 个元素开始的数组传递给 h
。 ``h 接收一个一维数组并减少指向数组的指针(不是它指向的值)因此不修改指向数组的值。
首先,所有三个函数都具有完全相同的签名。如果写成这样就不会那么混乱了:
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.
四次运算后结果k
为{ 1, 3, 3, 3 }
f和g是修改值,h是修改地址:
f(int k[0]){ --k[1]; }
f带一个参数,一个int数组; k[1] 在这种情况下与 k++ 相同;该函数正在递减位于下一个地址的元素的值与作为参数传递的元素的值。所以它在你的 main.
中递减 k[3]
g 相对简单,我想你已经明白了。
h 类似于 f
h(int k[1]){--k;}
h 接受一个 int 数组作为输入,它递减作为参数传递的地址。
希望对您有所帮助
稍微更改一下代码,您可以查看每个步骤的作用:
#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
#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
。
我不明白指令 --k[1]
在函数 f 中到底发生了什么。如果代码是 k[0]--
,我可以同意正确的输出。有什么不同?
谢谢
--k[1]
递减 k[1]
处的值,给定 f(k+2)
意味着 f()
-local k
指向调用者的(即 main()
's) k[2]
,加上 1 和 2 索引,您实际上是在将调用者的 k[3]
从 4 减少到 3.
k[0]--
会递减 *k
处的变量,对于 f
,在调用者的上下文中会被称为 k[2]
。
理解这段代码的重要见解是:
所有函数
f
、g
和h
最终得到一个指向int
的指针,以及它们的概念“k
" 完全独立于调用者的k
概念,具体来说 - 它在调用者的k
数组中偏移 2int
s,operator precedence:具体来说,在
[=48中的数组下标后应用前缀递减 =]--k[1]
.
话虽如此,paxdiablo 确实有道理……;-)。
这段代码的作用是:
将一个数组从
k[]
中的第 3 个元素开始传递到f
。f
采用一维数组并减少其第二个元素(在本例中为k[4]
,这会将其值 4 更改为 3)。将
k[]
中第3个元素的指针传递给g
。g
接受一个指向整数或数组的指针,首先减少指针的值(现在变成指向k[]
的第二个元素的指针)然后增加指向的值,将其从2 到 3.将一个从
k[]
中的第 3 个元素开始的数组传递给h
。 ``h 接收一个一维数组并减少指向数组的指针(不是它指向的值)因此不修改指向数组的值。
首先,所有三个函数都具有完全相同的签名。如果写成这样就不会那么混乱了:
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.
四次运算后结果k
为{ 1, 3, 3, 3 }
f和g是修改值,h是修改地址:
f(int k[0]){ --k[1]; }
f带一个参数,一个int数组; k[1] 在这种情况下与 k++ 相同;该函数正在递减位于下一个地址的元素的值与作为参数传递的元素的值。所以它在你的 main.
中递减 k[3]g 相对简单,我想你已经明白了。
h 类似于 f
h(int k[1]){--k;}
h 接受一个 int 数组作为输入,它递减作为参数传递的地址。
希望对您有所帮助
稍微更改一下代码,您可以查看每个步骤的作用:
#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