简体   繁体   English

为什么这两个局部变量的地址是一样的?

[英]Why are the addresses of these two local variables the same?

I have defined a function here that accepts an array as a parameter我在这里定义了一个接受数组作为参数的 function

void print(char ch[]);

When I call the function and give it the array as an argument当我调用 function 并将数组作为参数

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

And I print the addresses of these two variables in two different functions,我在两个不同的函数中打印这两个变量的地址,

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

the address of the array in the main function must be different from the address of the array as a parameter in the function I defined, but it is the same.主function中的数组地址必须和我定义的function中作为参数的数组地址不同,但是是一样的。 Why?为什么?

result of run this code运行此代码的结果

And whether the address of a variable can be negative?变量的地址是否可以为负?

Thanks for taking the time to read this question.感谢您花时间阅读这个问题。

 char ch[10];

This variable is an array.这个变量是一个数组。 It implicitly converts to a pointer to first element.它隐式转换为指向第一个元素的指针。 The value of the pointer is the address of the object that it points, and that address is the output that you see 1 .指针的值是它所指向的 object 的地址,而那个地址就是你看到的 output 1

 void print(char ch[]) {

This parameter is a pointer.这个参数是一个指针。 It may look like an array, but array parameters are adjusted to be pointers to the element of the array instead.它可能看起来像一个数组,但数组参数被调整为指向数组元素的指针。 When you output the value of a pointer, you see the address of the pointed object;当你 output 指针的值时,你看到指向的地址是 object; not the address of the variable that stores the pointer.不是存储指针的变量的地址。

Since the pointer that you passed as an argument points to the first element of the local array, the address that you see 1 is the same.由于您作为参数传递的指针指向本地数组的第一个元素,因此您看到的地址1是相同的。

The variables have different addresses, but the value of the parameter variable is the same as the address of the first element of the array variable.变量有不同的地址,但参数变量的值与数组变量的第一个元素的地址相同。


1 Except, you used the wrong format specifier that doesn't match the type of the argument, so the behaviour of the program is actually undefined. 1除了,您使用了与参数类型不匹配的错误格式说明符,因此程序的行为实际上是未定义的。 Don't do this.不要这样做。 If you absolutely must use printf , then you must use the %p format specifier and convert the argument to void* .如果您绝对必须使用printf ,那么您必须使用%p格式说明符并将参数转换为void*

You're right, two different arrays can't have the same address.没错,两个不同的 arrays 不能有相同的地址。

char ch[] is not an array though. char ch[]虽然不是数组。 Attempting to use an array as a function parameter silently creates a pointer instead, so in this case it means char *ch .尝试将数组用作 function 参数会默默地创建一个指针,因此在这种情况下它意味着char *ch (But char ch[10]; in main is still an array, since it's not a parameter.) (但char ch[10]; in main仍然是一个数组,因为它不是参数。)

ch (when applied to char ch[] parameter ) is not an address of ch . ch (当应用于char ch[]参数时)不是ch的地址。 It's an address that ch points to.这是ch指向的地址。 &ch would an address of ch itself, and it would have a different value. &ch将是ch本身的地址,并且它将具有不同的值。

But for char ch[10] in main , due to it being an array, ch and &ch have the same value (but different types: char * vs char (*)[10] (pointer to an array of 10 char)).但是对于main中的char ch[10] ,由于它是一个数组,因此ch&ch具有相同的值(但类型不同: char * vs char (*)[10] (指向 10 个字符的数组的指针))。

For starters to output a pointer you need to use the conversion specifier %p instead pf the conversion specifier %d .对于 output 的初学者,您需要使用转换说明符%p而不是转换说明符%d的指针。 Otherwise the call of printf invokes undefined behavior.否则printf的调用会调用未定义的行为。

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

Secondly within the function this call of printf does not output the address of the variable ch itself.其次,在 function 中,对printf的调用不会 output 变量ch本身的地址。 It outputs the address of the first element of the array pointed to by the pointer expression ch .它输出指针表达式ch指向的数组的第一个元素的地址。 As the array is not moved within memory then you will get the same value of the address.由于数组未在 memory 内移动,因此您将获得相同的地址值。

To output the address of the function parameter you need to write到 output 的地址 function 参数你需要写

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

Pay attention to that in this call在此通话中注意这一点

print(ch);

the array is implicitly converted to pointer to its first element.该数组被隐式转换为指向其第一个元素的指针。 And the compiler adjusts the function parameter having an array type to pointer to the array element type并且编译器将具有数组类型的function参数调整为指向数组元素类型的指针

void print(char *ch) {

There is a difference between these two calls of printf in main where the source array is declared and within the function printf这两个调用在声明源数组的 main 和 function 中存在差异

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

Within the function the first call outputs the address of the first element of the array pointed to by the pointer ch that is the address of the extent of memory occupied by the array.在 function 中,第一次调用输出指针ch指向的数组的第一个元素的地址,即该数组占用的 memory 的范围的地址。

The second call outputs the address of the local variable ch itself having the type char * (as pointed above).第二个调用输出具有char *类型的局部变量ch本身的地址(如上所述)。

In main these calls outputs the same value that is the address of the extent of memory occupied by the array.这些调用主要输出与数组占用的 memory 范围的地址相同的值。 The first call outputs the address of the first element of the array and the second call outputs the address of the array as a whole object.第一次调用输出数组第一个元素的地址,第二次调用输出整个数组的地址 object。 The both values are the initial address of the extent of memory occupied by the array.这两个值都是数组占用的memory的extent的起始地址。

As opposed to primitive types, arrays are always being passed to functions by address(as a pointer), even if you dont explicitly do it.与原始类型相反,arrays 总是通过地址(作为指针)传递给函数,即使你没有明确地这样做。 So the address of the array inside the function scope will be the same as address of it outside the scope.因此,function scope 内部的数组地址将与 scope 外部的地址相同。

Why are the addresses of these two local variables the same?为什么这两个局部变量的地址是一样的?

Passing a C-style array to a function actually passes its pointer to that function, not the whole array.C 样式数组传递给 function 实际上将其指针传递给 function,而不是整个数组。 This void print(char ch[]);这个void print(char ch[]); is the same as void print(char* ch);void print(char* ch);相同So both functions are printing the address of the same array in main function ( char ch[10]; ).所以这两个函数都在main function ( char ch[10]; ) 中打印相同数组的地址。

If you want to pass a copy of an array to a function, you can use std::array as below:如果要将数组的副本传递给 function,可以使用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;
}

Now the addresses won't be the same.现在地址将不一样了。

And whether the address of a variable can be negative?变量的地址是否可以为负?

Here:这里:

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

the above statement is interpreting ch (a pointer) as a decimal value (because of '%d' ).上面的语句将ch (指针)解释为十进制值(因为'%d' )。 That's why you're seeing a negative number.这就是为什么你看到一个负数。 You need to use %p instead:您需要改用%p

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM