为什么这两个局部变量的地址相同呢?

Why are the addresses of these two local variables the same?

我在这里定义了一个接受数组作为参数的函数

void print(char ch[]);

当我调用函数并将数组作为参数给它时

int main(){
    char ch[10];
    print(ch);
 }

然后我在两个不同的函数中打印这两个变量的地址,

 #include <stdio.h>
 
 void print(char ch[]) {
      printf("address of ch is %d\n",ch);
      
}

int main() {
     char ch[10];
     print(ch);
     printf("address of ch is %d\n",ch);
     return 0;
}

main函数中数组的地址肯定和我定义的函数中作为参数的数组地址不一样,但是是一样的。为什么?

以及变量的地址是否可以为负数?

感谢您花时间阅读这个问题。

你是对的,两个不同的数组不能有相同的地址。

char ch[] 虽然不是数组。尝试使用数组 作为函数参数 会默默地创建一个指针,因此在本例中它意味着 char *ch。 (但是 main 中的 char ch[10]; 仍然是一个数组,因为它不是参数。)

ch(其中 chchar ch[] 参数 )不是地址 of ch。这是 ch 指向的地址。 &ch 将是 ch 本身的地址,并且它具有不同的值。

但是对于main中的char ch[10],由于是数组,ch&ch的值相同(只是类型不同:char * vs char (*)[10](指向 10 个字符的数组的指针))。

char ch[10];

这个变量是一个数组。它隐式转换为指向第一个元素的指针。指针的值就是它指向的对象的地址,那个地址就是你看到的输出1.

void print(char ch[]) {

这个参数是一个指针。它可能看起来像一个数组,但数组参数被调整为指向数组元素的指针。当你输出一个指针的值时,你看到的是指向对象的地址;不是存储指针的变量的地址。

由于您作为参数传递的指针指向本地数组的第一个元素,因此您看到的地址1 是相同的。

变量地址不同,但参数变量的值与数组变量首元素地址相同


1 除非,您使用了与参数类型不匹配的错误格式说明符,因此程序的行为实际上是未定义的。不要这样做。如果绝对必须使用 printf,则必须使用 %p 格式说明符并将参数转换为 void*.

初学者要输出指针,您需要使用转换说明符 %p 而不是转换说明符 %d。否则 printf 的调用会调用未定义的行为。

printf("address of ch is %p\n", ( void * )ch);

其次,在函数中调用 printf 不会输出变量 ch 本身的地址。它输出指针表达式ch指向的数组第一个元素的地址。由于数组未在内存中移动,因此您将获得相同的地址值。

输出你需要写的函数参数的地址

void print(char ch[]) {
      printf("address of ch is %p\n", ( void * )&ch);
}

本次通话请注意

print(ch);

数组被隐式转换为指向其第一个元素的指针。并且编译器将数组类型的函数参数调整为指向数组元素类型的指针

void print(char *ch) {

printf 的这两个调用在声明源数组的 main 中和函数

中是有区别的
printf("address of ch is %p\n", ( void * )ch);
printf("address of ch is %p\n", ( void * )&ch);

在函数内,第一次调用输出指针ch指向的数组第一个元素的地址,即数组占用的内存范围的地址。

第二次调用输出局部变量 ch 本身具有类型 char * 的地址(如上所述)。

在 main 中,这些调用输出相同的值,即数组占用的内存范围的地址。第一次调用输出数组第一个元素的地址,第二次调用输出数组作为整个对象的地址。这两个值都是数组占用的内存范围的起始地址。

Why are the addresses of these two local variables the same?

C-style 数组传递给函数实际上传递的是指向该函数的指针,而不是整个数组。 void print(char ch[]);void print(char* ch); 相同,因此两个函数都在 main 函数 (char ch[10];) 中打印相同数组的地址。

如果要将数组的副本传递给函数,可以使用 std::array,如下所示:

#include <cstdio>
#include <array>


template<std::size_t N>
void print(std::array<char, N> ch) {
      printf("address of ch is %d\n", ch.data());
}

int main() {
    std::array<char, 10> ch;
    print(ch);
    printf("address of ch is %d\n", ch.data());
    return 0;
}

现在地址不一样了。

And whether the address of a variable can be negative?

这里:

printf("address of ch is %d\n",ch);

上面的语句将 ch(指针)解释为十进制值(因为 '%d')。这就是您看到负数的原因。您需要使用 %p 代替:

void print(char ch[]) {
      printf("address of ch is %p\n", (void*) &ch);
}