简体   繁体   中英

What is a pointer to an 'array of characters' in C?

int check_authentication(char *password) 
  // 1
{
int auth_flag = 0;
char password_buffer[16];

strcpy(password_buffer, password);      // 2
   if(strcmp(password_buffer, "brillig") == 0)
   auth_flag = 1;
   if(strcmp(password_buffer, "outgrabe") == 0)
   auth_flag = 1;
   return auth_flag;
}

check_authentication(argv[1]) // Passing a 'Command Line argument'
// ( which is a string in this example) to the check_authentication function.

I have two questions reg. the lines labelled 1 and 2 above,

  1. The function expects a character pointer as an argument. But we pass a "string" i,e an array of characters as an argument. How ?????

  2. The address held by the pointer "password" (that points to a character) is copied to the "password_buffer" array. It makes no sense to me . Pls explain.

  1. You are passing a character pointer which points to the first character in the string. You aren't actually passing the whole string.

  2. The strcpy function reads the character being pointed to by this pointer, and then keeps reading successive characters from the next memory location until it encounters a null terminator.

The first argument of strcpy , and both arguments of strcmp , work in the same way.

The function expects a character pointer as an argument. But we pass a "string" i,e an array of characters as an argument. How ?????

Except when it is the operand of the sizeof or unary & operators, or is a string literal being used to initialize another array in a declaration, an expression of type "N-element array of T " will be converted ("decay") to an expression of type "pointer to T ", and the value of the expression will be the address of the first element of the array.

When you call

strcpy(password_buffer, password);

the expression password_buffer has type "16-element array of char "; since the expression is not the operand of the sizeof or unary & operators, the expression is converted ("decays") to type "pointer to char ", and the value of the expression is the address of the first element. This pointer value is what gets passed to strcpy .

In short, any time you pass an array expression to a function, the function will receive a pointer value. In the context of a function parameter declaration, T a[] and T a[N] will be interpreted as T *a .

Believe it or don't, Ritchie did have reasons for designing the language this way; refer to this paper for details (look for the section titled "Embryonic C").

The address held by the pointer "password" (that points to a character) is copied to the "password_buffer" array. It makes no sense to me . Pls explain.

That's not what's happening; what's happening is that strcpy is copying the contents of the buffer starting at the address given by password to password_buffer . Imagine the following memory map:

Item              Address                0x00  0x01  0x02  0x03
----              -------                ----  ----  ----  ----
"foo"             0x7fffc7cf4b22          'f'   'o'   'o'     0

argv[1]           0x7fffc7cf2670         0x00  0x00  0x7f  0xff
                                         0xc7  0xcf  0x4b  0x22

password          0x7ffffdbe1878         0x00  0x00  0x7f  0xff  
                                         0xfd  0xbe  0x2v  0x22

password_buffer   0x7ffffdbe1880         0x??  0x??  0x??  0x??
                                         0x??  0x??  0x??  0x??
                                         0x??  0x??  0x??  0x??
                                         0x??  0x??  0x??  0x??

where 0x?? indicates an unknown/indeterminate byte value.

The command line argument string "foo" is stored at address 0x7fffc7cf4b22 . Note that in C, a string is simply a sequence of character values terminated by a 0-valued byte. Strings are stored as arrays of char ( const char in C++), but not all arrays of char contain a string.

The argv[1] expression evaluates to the address of the first command line argument, which is the address of the string "foo" , which is 0x7fffc7cf4b22 . This value is passed to the check_authentication function and is stored to the password parameter. Note that argv[1] and password are different items in memory (they have different addresses), but both contain the same value (the address of the string "foo" ).

The password_buffer array starts at address 0x7ffffdbe1880 . Since it wasn't declared static and doesn't have an explicit initializer, the contents of the array are indeterminate .

The strcpy function copies the contents of the string starting at address 0x7fffc7cf4b22 into the buffer starting at address 0x7ffffdbe1880 until it sees that 0-valued byte. After the call to strcpy , our memory looks like this:

Item              Address                0x00  0x01  0x02  0x03
----              -------                ----  ----  ----  ----
"foo"             0x7fffc7cf4b22          'f'   'o'   'o'     0

argv[1]           0x7fffc7cf2670         0x00  0x00  0x7f  0xff
                                         0xc7  0xcf  0x4b  0x22

password          0x7ffffdbe1878         0x00  0x00  0x7f  0xff  
                                         0xfd  0xbe  0x2v  0x22

password_buffer   0x7ffffdbe1880          'f'   'o'   'o'     0
                                         0x??  0x??  0x??  0x??
                                         0x??  0x??  0x??  0x??
                                         0x??  0x??  0x??  0x??

Strings are really just arrays of characters that are terminated with a null byte \\0 . The array is the string itself, the char pointer however is the memory location of the zeroth position of the array.

strcpy reads characters beginning from the memory location pointed at by the char pointer until it encounters the null termination character.

  1. Array actually isn't passed as such. What gets passed is a pointer to the very first element of the array. A string in C is actually an array of chars with a terminating NUL and it's a pointer to its first element that gets passed.

  2. You really should read strcpy manpage carefully http://linux.die.net/man/3/strcpy . No addresses ever get copied there. All the function does is taking a string (an array of chars) password pointer points at and copy all the chars found at that address up to the NUL to the address pointed by password_buffer pointer.

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