【问题标题】:Why are the addresses of these two local variables the same? [duplicate]为什么这两个局部变量的地址是一样的? [复制]
【发布时间】:2022-01-24 17:40:43
【问题描述】:

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

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函数中的数组地址,必须和我定义的函数中作为参数的数组地址不同,但是是一样的。为什么?

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

感谢您抽出宝贵时间阅读此问题。

【问题讨论】:

    标签: c++ arrays c pointers printf


    【解决方案1】:
    char ch[10];
    

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

    void print(char ch[]) {
    

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

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

    变量地址不同,但参数变量的值与数组变量第一个元素的地址相同。


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

    【讨论】:

      【解决方案2】:

      对于要输出指针的初学者,您需要使用转换说明符%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 中,这些调用输出与数组占用的内存范围地址相同的值。第一次调用输出数组第一个元素的地址,第二次调用将数组的地址作为整个对象输出。这两个值都是数组占用的内存范围的初始地址。

      【讨论】:

        【解决方案3】:

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

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

        ch(其中chchar ch[] 参数)不是ch地址。这是ch 指向的地址。 &amp;ch 本身就是ch 的地址,它的值会不同。

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

        【讨论】:

          【解决方案4】:

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

          C 风格 数组传递给函数实际上是将其指针传递给该函数,而不是整个数组。这个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;
          }
          

          现在地址将不一样了。

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

          这里:

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

          上述语句将ch(指针)解释为十进制值(因为'%d')。这就是为什么你看到一个负数。您需要改用%p

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-01-04
            • 2018-09-14
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多