char * argv[] 是指针数组或 char 字符串数组

char * argv[] is an array of pointers or array of char strings

据我目前的理解, char * argv[] = {"abc", "def"}; 初始化一个包含 2 char 个指针的数组。第一个指向 "abc",第二个指向 "def"。而名字argv也是一个指针,指向数组argv.

中的第一个指针

为什么有人说 argvchar 字符串数组呢? (就像在 K&R 的 C 编程语言中一样)。它们不是指指向 char 的指针数组吗,这本书也有解释。

如果我的假设是正确的,printf("%s", argv[1]) 中的 %s 根本不需要 char string,而是指向 char string?[=25 的指针=]

感谢您的耐心等待!

我读过的东西:

Pointer to Pointer with argv

如 C 标准中所用,“A string 是由第一个空字符终止并包括第一个空字符的连续字符序列”(C 2018 7.1.1 1)。它不是 char *char * 可能指向字符串的第一个字符,有时在 C 标准中称为指向字符串的指针,但这是草率的术语,因为 char * 必然是指向字符的指针—对于指向“序列”的含义没有技术定义,尽管我们可以将其理解为指向序列的第一个元素。

From my understanding so far, char * argv[] = {"abc", "def"}; initialises an array of 2 char pointers.

没错。

And the name argv is also a pointer that points to the first pointer in the array argv.

考虑到问题中 argv 的定义,这是不正确的。定义 char * argv[] = {"abc", "def"};argv 定义为 char * 的数组。它不是指针。

当数组被用作sizeof或一元&的操作数时,它被当作一个数组来操作。 (此外,当用字符串文字初始化数组时,字符串文字用作数组。)除了这些情况,当在表达式中使用数组时,它会转换为指向其第一个元素的指针。这种转换是自动的,而且很常见,以至于学生可能会将数组或数组的名称误认为是转换成的指针。那是一个错误。该数组不是指针。

Why does some say argv is an array of char strings then? (like in the C Programming Language by K&R).

Kernighan 和 Ritchie 在 The C Programming Language 的任一版本中都没有在索引中为 argv 列出的任何地方提到这一点。在 1978 年的第一版中,他们在第 110 页说“第二个 (argv) 是指向包含参数的字符串数组的指针,每个字符串一个。”在 1988 年的第二版中,他们在第 114 页说“第二个(argv,用于参数向量)是指向包含参数的字符串数组的指针,每个字符串一个。”该索引还为 argv 列出了第 163 页,但那里只是偶然提及,指的是程序名称的 argv[0]

请注意,他们将 argv 称为指针而不是数组。这是因为 mainargv 参数是一个指针。虽然可以用int main(int argc, char *argv[])声明,但声明为数组的参数会自动调整为指针。因此 main 声明中的 char *argv[]argv 定义为与您显示的语句 char * argv[] = {"abc", "def"}; 不同的东西。在参数声明中,自动调整为指针。在单独的定义中,它是一个数组。

尽管 Kernighan 和 Ritchie 确实将 argv 称为指针,而不是您所写的数组,但他们说它是“指向数组的指针”。这也是草率的术语。它的类型是pointer-to-pointer-to-char,而不是pointer-to-array-of-char。它是指向数组的指针,仅在它是指向 char.

数组的第一个元素的指针的意义上

If my hypothesis is correct, the %s in printf("%s", argv[1]) is not expecting a char string at all, rather, a pointer to the char string?

Per C 2018 7.21.6.1 8,对于 s 没有修饰符或精度的 printf 说明符,“参数应是指向字符数组初始元素的指针类型。数组中的字符被写入(但不包括)终止空字符。”因此,应该传递指向字符串首字符的 char *(或 signed char *unsigned char *)。

Char **argv 指向一个参数,以及该参数中的一个字符。

示例:

/* ************************************************************************** */
/*                                                                            */
/*                                                        :::      ::::::::   */
/*   temp.c                                             :+:      :+:    :+:   */
/*                                                    +:+ +:+         +:+     */
/*   By: albarret <marvin@42.fr>                    +#+  +:+       +#+        */
/*                                                +#+#+#+#+#+   +#+           */
/*   Created: 2019/07/05 20:14:37 by albarret          #+#    #+#             */
/*   Updated: 2019/07/05 20:17:41 by albarret         ###   ########.fr       */
/*                                                                            */
/* ************************************************************************** */

#include <unistd.h>

void    ft_putchar(char c)
{
    write(1, &c, 1);
}

int     main(int argc, char **argv)
{
    int i;

    i = 0;
    if (argc < 2)
    {
        write(1, "\n", 1);
        return (0);
    }
    while (argv[1][i])
    {
        ft_putchar(argv[1][i]);
        i++;
    }
    write(1, "\n", 1);
    return (0);
}