C 两个整数变量驻留在一个内存地址?

C 两个整数变量驻留在一个内存地址?,c,pointers,memory,C,Pointers,Memory,我正在学习C语言的指针,并试图解决在线可用指针的练习。虽然下面的问题没有使用指针,但我知道错误的输出是由于没有使用指针。问题是: /* p2.c Find out (add code to print out) the address of the variable x in foo1, and the variable y in foo2. What do you notice? Can you explain this? */ 这是我的答案- #include <stdio.h

我正在学习C语言的指针,并试图解决在线可用指针的练习。虽然下面的问题没有使用指针,但我知道错误的输出是由于没有使用指针。问题是:

/* p2.c 
Find out (add code to print out) the address of the variable x in foo1, and the 
variable y in foo2. What do you notice? Can you explain this? 
*/
这是我的答案-

#include <stdio.h>
void foo1(int xval) 
{ 
 int x; 
 x = xval; 
 /* print the address and value of x here */ 
 printf("\n Address of variable x is:%p\n", &x);
 printf("\n Value of variable x is: %d\n", x); 

} 
void foo2(int dummy) 
{ 
 int y;
 y=dummy; 
 /* print the address and value of y here */ 
 printf("\n Address of variable y is:%p\n", &y);
 printf("\n Value of variable y is: %d\n", y); 
} 

int main() 
{ 
 foo1(7); 
 foo2(11); 

 return 0; 
} 
据我所知,当程序运行时,调用带有整数作为函数参数的
foo1
时,整数
7
被获取并存储在整数变量
x
中。函数
foo1
然后打印变量
x
的地址和值。同样的事情在函数
foo2
中重复

但是,我不明白为什么两个具有不同值的整数变量驻留在同一个内存地址
0x7fff558fcb98
?这是不是因为C语言中的内存管理问题(
malloc
free
等等——我还没有做到!)


任何帮助都将不胜感激。谢谢。

原因是这些变量位于调用堆栈上,并且相同的内存位置可用于后续调用。要获得我认为您正在寻找的行为,请在单个函数中声明这两个变量,并将输出语句放在它们旁边,而不是放在另一个作用域中

void foo1(int-xval)
void foo2(int-dummy)
是两个不同的函数,因此当一个函数运行时,只有该函数的变量驻留在堆栈中。一旦调用另一个函数或从函数返回,该函数的局部变量就会出现在堆栈中。因此,不同函数的两个变量可以有相同的地址(但在不同的时间)

大多数编译器在函数内部时在堆栈上分配局部变量

当函数返回时,内存返回到系统,另一个函数可以自由地将内存重新用于另一个局部变量

换句话说,这里发生的是
foo1
x
分配内存,但当它返回时,内存将返回到系统,因为
x
不再使用

然后在
foo2
中重复使用相同的内存地址来存储
y


请注意,堆栈上的内存不是使用malloc分配的,堆栈指针基本上只是一个指针,在函数输入和退出时会自动移动。

看看“静态”和“自动”内存分配之间的区别。您正在函数声明中使用自动内存分配,并且在函数退出时释放内存:

当您声明自动变量(如函数参数或局部变量)时,会发生自动分配。自动变量的空间在输入包含声明的复合语句时分配,在退出该复合语句时释放。在GNUC中,自动存储的大小可以是一个不同的表达式。在其他C实现中,它必须是常量


底线。在foo1(7)退出后,相同的内存被用于foo2(11)中的7,并被重用为11

您现在一定已经阅读了有关存储类的内容,请尝试在此处进行关联。在这里,实际使用的存储类是automatic

主-->foo1-->分配x-->在foo1-->中执行工作释放x-->调用foo2使用的内存位置,然后为y重复对x执行的操作(此处将使用从x中释放的相同内存位置)

这并不是因为您没有使用指针。 您可能希望(您应该尝试)像下面这样使用指针,但希望再次得到相同的结果:

#include <stdio.h>
void foo1(int xval) 
{ 
 int *x; 
 x = &xval; 
 /* print the address and value of x here */ 
 printf("\n Address of variable pointed by x is:%p\n", x);
 printf("\n Value of variable x is: %d\n", *x); 

} 
void foo2(int dummy) 
{ 
 int *y;
 y=&dummy; 
 /* print the address and value of y here */ 
 printf("\n Address of variable y is:%p\n", y);
 printf("\n Value of variable y is: %d\n", *y); 
} 

int main() 
{ 
 foo1(7); 
 foo2(11); 

 return 0; 
} 
#包括
void foo1(int xval)
{ 
int*x;
x=&xval;
/*在此处打印x的地址和值*/
printf(“\n x所指变量的地址为:%p\n”,x);
printf(“\n变量x的值为:%d\n”,*x);
} 
void foo2(int虚拟)
{ 
int*y;
y=&dummy;
/*在此处打印y的地址和值*/
printf(“\n变量y的地址是:%p\n”,y);
printf(“\n变量y的值为:%d\n”,*y);
} 
int main()
{ 
foo1(7);
foo2(11);
返回0;
} 

可视化堆栈状态有助于理解行为。在main中,假设堆栈如下所示:

当您输入
foo1
时,
foo1
的堆栈帧将添加到堆栈中,如下所示:

foo1
返回时,堆栈将恢复为:

当您输入
foo2
时,
foo2
的堆栈帧将添加到堆栈中,如下所示:

对于
foo1
foo2
,堆栈帧的状态看起来非常相似。局部变量
x
y
的地址相同,这并不奇怪


如果参数的数量、参数类型或局部变量类型不同,您可能会注意到局部变量地址的不同值。

您可能正在查找以下内容:

 main()                                                           
   {
       char   a;                                                    
       int    x;                                                    
       float  p, q;                                                 

       a  = 'A';                                                    
       x  = 125;                                                    
       p  = 10.25, q = 18.76;                                       
       printf("%c is stored at addr %u.\n", a, &a);                 
       printf("%d is stored at addr %u.\n", x, &x);                 
       printf("%f is stored at addr %u.\n", p, &p);                
       printf("%f is stored at addr %u.\n", q, &q);                 

       }


函数局部变量进入堆栈。此外,函数局部变量仅在函数执行时存在,它们超出范围,并在函数返回时消失。了解堆栈是如何工作的,你应该有你的答案。。。也来看看@
 main()                                                           
   {
       char   a;                                                    
       int    x;                                                    
       float  p, q;                                                 

       a  = 'A';                                                    
       x  = 125;                                                    
       p  = 10.25, q = 18.76;                                       
       printf("%c is stored at addr %u.\n", a, &a);                 
       printf("%d is stored at addr %u.\n", x, &x);                 
       printf("%f is stored at addr %u.\n", p, &p);                
       printf("%f is stored at addr %u.\n", q, &q);                 

       }
// Declare and initialize an int variable

int var = 34;

// Declare a pointer to int variable

int *ptr;

// Initialize ptr to point to variable var

ptr = &var;



// Access var directly and indirectly

printf("\nDirect access, variable var value = var = %d", var);

// you can use %p for the pointer memory address directly or

// %0x or %0X or %p in hexadecimal representative instead of

// %d, just to avoid confusion here

printf("\nIndirect access, variable var value = *ptr = %d", *ptr);

// Display the address of var two ways

printf("\n\nThe memory address of variable var = &var = %p", &var);

printf("\nThe memory address of variable var = ptr = %p\n", ptr);