简体   繁体   中英

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

From my understanding so far, char * argv[] = {"abc", "def"}; initialises an array of 2 char pointers. First one points to "abc" , the second to "def" . And the name argv is also a pointer that points to the first pointer in the array argv .

Why does some say argv is an array of char strings then? (like in the C Programming Language by K&R). Don't they mean an array of pointers to char s, which the book also explains.

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 ?

Thanks for your patience!

Stuff i've read:

Pointer to Pointer with argv

C: Accessing the second argv via a pointer

As used in the C standard, “A string is a contiguous sequence of characters terminated by and including the first null character” (C 2018 7.1.1 1). It is not a char * . A char * may point to the first character of a string and is sometimes referred to in the C standard as a pointer to a string, but this is sloppy terminology as a char * is necessarily a pointer to a character—there is no technical definition for what it means to point to a “sequence,” although we may take it to mean to point to the first element of a sequence.

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

That is correct.

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

That is not correct given the definition of argv in the question. The definition char * argv[] = {"abc", "def"}; defines argv to be an array of char * . It is not a pointer.

When an array is used as the operand of sizeof or unary & , it is operated on as an array. (Also, when an array is initialized with a string literal, the string literal is used as an array.) Other than these circumstances, when an array is used in an expression, it is converted to a pointer to its first element. This conversion is automatic and is so common that students may mistake the array, or the name of the array, for the pointer it is converted to. That is a mistake. The array is not a pointer.

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

Kernighan and Ritchie do not say this in either edition of The C Programming Language in any of the places listed for argv in the index. In the first edition, 1978, they say on page 110 “the second ( argv ) is a pointer to an array of character strings that contain the arguments, one per string.” In the second edition, 1988, they say on page 114 “the second ( argv , for argument vector) is a pointer to an array of character strings that contain the arguments, one per string.” The index also lists page 163 for argv , but there is just an incidental mention there, referring to argv[0] for the program name.

Note that they refer to argv as a pointer rather than an array. This is because the argv parameter to main is a pointer. Although it may be declared with int main(int argc, char *argv[]) , a parameter that is declared as an array is automatically adjusted to be a pointer. Thus char *argv[] in the declaration of main defines argv to be something different from the statement you showed, char * argv[] = {"abc", "def"}; . In the parameter declaration, it is automatically adjusted to be a pointer. In the separate definition, it is an array.

Although Kernighan and Ritchie do refer to argv as a pointer, not an array as you wrote, they says it is a “pointer to an array.” This is also sloppy terminology. Its type is pointer-to-pointer-to- char , not pointer-to-array-of- char . It is a pointer to an array only in the sense that it is a pointer to the first element of an array of 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, for an s specifier to printf without a modifier or a precision, “the argument shall be a pointer to the initial element of an array of character type. Characters from the array are written up to (but not including) the terminating null character.” Thus, one should pass a char * (or a signed char * or unsigned char * ) that points to the initial character of a string.

Char **argv points to an argument, and a character in that argument.

Example:

/* ************************************************************************** */
/*                                                                            */
/*                                                        :::      ::::::::   */
/*   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);
}

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