你能解释一下下一个代码示例背后的机制(我想我知道,但我需要第二意见):
1)--------------------------
using namespace std;
int * f(int x) {
return &x;
}
int * g(int x, int y) {
return &y;
}
int * h(int x, int y, int z) {
return &z;
}
int main() {
cout << *f(42) << endl;
int * y1 = g(43, 44);
int * y2 = g(45, 46);
cout << *y1 << ", " << *y2 << endl;
int * z1 = h(47, 48, 49);
int * z2 = h(50, 51, 52);
cout << *z1 << ", " << *z2 << endl;
return 0;
}
2)--------------------------
int *a, *b;
void f(int x) {
int i[3];
i[0] = x;
i[1] = x + 1;
i[2] = x + 2;
a = i;
}
void g(int x) {
int i[3];
i[0] = x;
i[1] = x + 1;
i[2] = x + 2;
b = i;
}
int main() {
f(1);
printf("a = {%d,%d,%d}\n", a[0], a[1], a[2]);
g(2);
printf("a = {%d,%d,%d}\n", a[0], a[1], a[2]);
}
3)--------------------------
int main() {
char * hello = "hello, world!" + 3;
char * charstring = 'h' + "ello, world!";
printf("hello=%s, charstring=%s.\n", hello, charstring);
return 0;
}
谢谢。
答案 0 :(得分:6)
我希望这些程序在运行时崩溃或做其他奇怪的事情。
示例1:函数f
,g
和h
返回其参数的内存地址。请注意,这些参数存储在堆栈中,当函数返回时,堆栈被展开,地址将不再有效。你可以幸运,价值仍然存在,但你也可以让程序崩溃或返回一些随机值,而不是你传递给函数的值。
示例2:函数f
和g
将全局变量a
和b
设置为函数中声明的局部变量的地址。就像在第一个例子中一样,当函数返回时,那些局部变量将消失,使a
和b
指向无效的东西。
示例3:这是奇怪的指针算法。 hello
可能会指向文本的地址加上3,所以你可能会得到“lo,world!”为此打印(但也可能不同,具体取决于指针算法在您的特定平台上的工作方式)。 charstring
的情况类似,只有在这里添加'h'
(ASCII值104 - 所以你要向指针添加104)。这很可能会使程序崩溃。
答案 1 :(得分:3)
如果您逐步解释后台发生的事情,我认为初学者更容易理解这些概念。
1
cout << *f(42) << endl; // Call f with the value 42
int * f(int x) { // Push an integer, x, on the stack (x = 42)
return &x; // Return a pointer to var x
} // Pop x off the stack
// Pointer now points to a memory address that is unallocated,
// which will crash the program when it tries to use that memory,
// which it does with cout
2
f(1); // Call f with the value 1
void f(int x) { // Push an integer, x, on the stack (x = 1)
int i[3]; // Declare an int* with space for 3 vals (local! stack!)
i[0] = x; // Define values of the array
a = i; // Set a equal to i, beginning of array
} // i is now out of scope, and since it was declared as locally,
// rather than with malloc (or new in c++), it is on the stack
// and has now been popped off, so a points to a memory address
// that the OS *should* have marked as inaccessible
3
char * hello = "hello, world!" + 3; // hello is a char*, a pointer that
// points to the beginning of an array
// of characters. Adding 3 will increment
// the pointer three characters after the
// first character.
char * charstring = 'h' + "ello, world!"; // charstring is a char*, a pointer that
// points to the beginning of an array
// of characters. This time, it would point
// to "ello, world!". However, the addition
// of 'h' will shift the character position
// by 104 characters because that is the
// value of ascii 'h'.