简体   繁体   中英

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

I have defined a function here that accepts an array as a parameter

void print(char ch[]);

When I call the function and give it the array as an argument

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. 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 .

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

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. Don't do this. If you absolutely must use printf , then you must use the %p format specifier and convert the argument to void* .

You're right, two different arrays can't have the same address.

char ch[] is not an array though. Attempting to use an array as a function parameter silently creates a pointer instead, so in this case it means char *ch . (But char ch[10]; in main is still an array, since it's not a parameter.)

ch (when applied to char ch[] parameter ) is not an address of ch . It's an address that ch points to. &ch would an address of ch itself, and it would have a different value.

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)).

For starters to output a pointer you need to use the conversion specifier %p instead pf the conversion specifier %d . Otherwise the call of printf invokes undefined behavior.

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. It outputs the address of the first element of the array pointed to by the pointer expression ch . As the array is not moved within memory then you will get the same value of the address.

To output the address of the function parameter you need to write

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

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("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.

The second call outputs the address of the local variable ch itself having the type char * (as pointed above).

In main these calls outputs the same value that is the address of the extent of memory occupied by the array. 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. The both values are the initial address of the extent of memory occupied by the array.

As opposed to primitive types, arrays are always being passed to functions by address(as a pointer), even if you dont explicitly do it. So the address of the array inside the function scope will be the same as address of it outside the 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. This void print(char ch[]); is the same as void print(char* ch);So both functions are printing the address of the same array in 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:

#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' ). That's why you're seeing a negative number. You need to use %p instead:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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