什么是 C 中指向 'array of characters' 的指针?

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.

我有两个问题。上面标记为 1 和 2 的行,

  1. 该函数需要一个字符指针作为参数。但是我们传递了一个 "string" 即一个字符数组作为参数。怎么样?????

  2. 指针"password"(指向一个字符)持有的地址被复制到"password_buffer"数组。对我来说完全是无稽之谈 。请解释一下。

  1. 您正在传递指向字符串中第一个字符的字符指针。您实际上并没有传递整个字符串。

  2. strcpy函数读取这个指针指向的字符,然后从下一个内存位置继续读取连续的字符,直到遇到空终止符。

strcpy 的第一个参数和 strcmp 的两个参数以相同的方式工作。

字符串实际上只是以空字节结束的字符数组[=10=]。数组是字符串本身,但是 char 指针是数组第 0 个位置的内存位置。

strcpy 从 char 指针指向的内存位置开始读取字符,直到遇到空终止字符。

  1. 数组实际上并不是这样传递的。传递的是指向数组第一个元素的指针。 C 中的字符串实际上是一个以 NUL 结尾的字符数组,它是指向传递的第一个元素的指针。

  2. 您真的应该仔细阅读 strcpy 联机帮助页 http://linux.die.net/man/3/strcpy。没有地址被复制到那里。该函数所做的就是获取一个字符串(字符数组)password 指针指向并将在该地址找到的所有字符复制到 NULpassword_buffer 指针指向的地址.

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

除非它是 sizeof 或一元 & 运算符的操作数,或者是用于在声明中初始化另一个数组的字符串文字,表达式 类型 "N-element array of T" 将被转换 ("decay") 为类型 "pointer to T" 的表达式,表达式的值将是数组第一个元素的地址。

当你打电话时

strcpy(password_buffer, password);

表达式 password_buffer 的类型为“char 的 16 元素数组”;因为表达式不是 sizeof 或一元 & 运算符的操作数,所以表达式被转换 ("decays") 为类型 "pointer to char",并且表达式的值是第一个元素的地址。这个指针值是传递给 strcpy 的值。

简而言之,任何时候将数组表达式传递给函数时,函数都会收到一个指针值。在函数参数声明的上下文中,T a[]T a[N] 将被解释为 T *a

信不信由你,Ritchie 确实有这样设计语言的理由;有关详细信息,请参阅 this paper(查找标题为 "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.

事实并非如此;正在发生的事情是 strcpy 正在复制缓冲区的 内容 ,从 password 给定的地址开始到 password_buffer。想象一下下面的内存映射:

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

其中 0x?? 表示 unknown/indeterminate 字节值。

命令行参数字符串 "foo" 存储在地址 0x7fffc7cf4b22。请注意,在 C 中,string 只是一个以 0 值字节结尾的字符值序列。字符串存储为 char 的数组(在 C++ 中为 const char),但并非所有 char 的数组都包含字符串。

argv[1] 表达式计算第一个命令行参数的地址,即字符串 "foo" 的地址,即 0x7fffc7cf4b22。此值传递给 check_authentication 函数并存储到 password 参数。注意 argv[1]password 在内存中是不同的项(它们有不同的地址),但都包含相同的 value (字符串的地址 "foo").

password_buffer 数组从地址 0x7ffffdbe1880 开始。由于它没有声明 static 并且没有显式初始化程序,因此数组的内容是 不确定的

strcpy 函数将从地址 0x7fffc7cf4b22 开始的字符串内容复制到从地址 0x7ffffdbe1880 开始的缓冲区中,直到它看到该值为 0 的字节。在调用 strcpy 之后,我们的内存是这样的:

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