C提示和技巧解释

时间:2011-04-15 11:30:06

标签: c++

你能解释一下下一个代码示例背后的机制(我想我知道,但我需要第二意见):

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;
}

谢谢。

2 个答案:

答案 0 :(得分:6)

我希望这些程序在运行时崩溃或做其他奇怪的事情。

示例1:函数fgh返回其参数的内存地址。请注意,这些参数存储在堆栈中,当函数返回时,堆栈被展开,地址将不再有效。你可以幸运,价值仍然存在,但你也可以让程序崩溃或返回一些随机值,而不是你传递给函数的值。

示例2:函数fg将全局变量ab设置为函数中声明的局部变量的地址。就像在第一个例子中一样,当函数返回时,那些局部变量将消失,使ab指向无效的东西。

示例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'.