Provavelmente é uma questão de conveniência. Fornece ao programador uma maneira fácil de escapar mais cedo se não houver argumentos suficientes, sem loop. Caso contrário, certamente teríamos funções chamadas int argc(char *argv[])fazendo exatamente isso :-))
cnicutar
5
Só para ficar claro, "\0"não é o mesmo que ponteiro NULL ( 0é equivalente a NULL em C ++)
Mats Petersson
31
Por que precisamos que argv [argc] seja NULL se temos argc?
Ambroz Bizjak
7
De que outra forma você determinaria o número de argumentos em tempo constante?
avakar
4
Não pense que as tags linux / unix são apropriadas aqui, pois esse comportamento deve ser verdadeiro para todos os compiladores em todos os sistemas operacionais.
Darrel Hoffman
Respostas:
106
Sim, argv[argc]==NULLé garantido. Veja C11 5.1.2.2.1 Inicialização do programa (ênfase minha)
Se forem declarados, os parâmetros para a função principal devem obedecer às seguintes restrições:
O valor de argc deve ser não negativo.
argv [argc] deve ser um ponteiro nulo.
Fornecer, argcportanto, não é vital, mas ainda é útil. Entre outras coisas, permite verificar rapidamente se o número correto de argumentos foi passado.
Edit: A questão foi alterada para incluir C ++. n3337 draft 3.6.1 Função principal diz
2 ... argc será o número de argumentos transmitidos ao programa a partir do ambiente em que o programa é executado. .... O valor de argc deve ser não negativo. O valor de argv [argc] deve ser 0 .
E argcpoderia ser muito grande, porque o shell está fazendo de expansão (por isso, ls *o *é expandida pelo shell antes execvede /bin/lsexecutável). No meu sistema, posso ter argcvárias centenas de milhares.
Basile Starynkevitch
Isso é muito legal, isso nunca me ocorreu pois sempre considerei argcsuficiente, mas posso definitivamente pensar em situações em que essa garantia seria relevante e até exigida. +1
Thomas
6
@BasileStarynkevitch O tempo de simplesmente percorrer uma matriz de valores de ponteiro uma vez a mais até NULL, para obter a contagem, é minúsculo em comparação com o tempo já gasto na geração da matriz de ponteiros e ainda mais irrelevante em comparação ao uso real de cada valor de argumento no programa. E se apenas verificar se a contagem de argumentos é maior do que N, não é necessário percorrer o array inteiro. Ainda assim, concordo plenamente, isso argcfoi e é uma coisa boa.
hyde
43
Sim, argv[argc]é garantido que seja um ponteiro nulo. argcé usado por conveniência.
Citando a explicação oficial do Racional C99, observe as palavras verificação redundante :
A especificação de argce argvcomo argumentos para mainreconhecer a prática anterior extensa. argv[argc]deve ser um ponteiro nulo para fornecer uma verificação redundante para o final da lista, também com base na prática comum.
É por razões históricas e compatibilidade com o código antigo. Originalmente, não havia garantia de que existiria um ponteiro nulo como o último elemento da matriz argv. Mas argc sempre existiu.
... O que é uma pena, de certa forma. Se tivéssemos int main(char *argv[], int argc, ...), alguns programas poderiam simplesmente omitir o argcporque não precisam dele. O oposto (necessário, argcmas não argv) provavelmente nunca é útil em um programa real.
hyde,
@hyde: veja o comentário acima de Basile Starynkevitch
zentrunix
6
Nós "precisamos" disso, porque é exigido por vários padrões.
Somos livres para ignorar o valor completamente, mas como é o primeiro parâmetro de main, devemos tê-lo na lista de parâmetros. Em C ++ (e provavelmente em dialetos C não padrão), você pode simplesmente omitir o nome do parâmetro, como este snippet C ++ (fácil de converter para C):
#include<stdio.h>// C-compatible include, guarantees puts in global namespace// program will print contents of argv, one item per line, starting from argv[0]int main(int/*argc*/,char*argv[]){// uncomment argc for C//(void)argc; // uncomment statement for Cfor(int i=0; argv[i];++i){
puts(argv[i]);}return0;}
No C padrão, com configurações de avisos comuns, o parâmetro não utilizado gera um aviso, que pode ser corrigido por uma instrução como a (void)argc;que faz com que o nome seja usado sem gerar nenhum código.
argcé bom ter, porque de outra forma muitos programas precisariam percorrer os parâmetros para obter a contagem. Além disso, em muitas linguagens de programação com arrays que têm comprimento, não existe nenhum argcparâmetro, há apenas um array com os itens.
int argc(char *argv[])
fazendo exatamente isso :-))"\0"
não é o mesmo que ponteiro NULL (0
é equivalente a NULL em C ++)Respostas:
Sim,
argv[argc]==NULL
é garantido. Veja C11 5.1.2.2.1 Inicialização do programa (ênfase minha)Fornecer,
argc
portanto, não é vital, mas ainda é útil. Entre outras coisas, permite verificar rapidamente se o número correto de argumentos foi passado.Edit: A questão foi alterada para incluir C ++. n3337 draft 3.6.1 Função principal diz
fonte
argc
poderia ser muito grande, porque o shell está fazendo de expansão (por isso,ls *
o*
é expandida pelo shell antesexecve
de/bin/ls
executável). No meu sistema, posso terargc
várias centenas de milhares.argc
suficiente, mas posso definitivamente pensar em situações em que essa garantia seria relevante e até exigida. +1argc
foi e é uma coisa boa.Sim,
argv[argc]
é garantido que seja um ponteiro nulo.argc
é usado por conveniência.Citando a explicação oficial do Racional C99, observe as palavras verificação redundante :
fonte
É por razões históricas e compatibilidade com o código antigo. Originalmente, não havia garantia de que existiria um ponteiro nulo como o último elemento da matriz argv. Mas argc sempre existiu.
fonte
int main(char *argv[], int argc, ...)
, alguns programas poderiam simplesmente omitir oargc
porque não precisam dele. O oposto (necessário,argc
mas nãoargv
) provavelmente nunca é útil em um programa real.Nós "precisamos" disso, porque é exigido por vários padrões.
Somos livres para ignorar o valor completamente, mas como é o primeiro parâmetro de
main
, devemos tê-lo na lista de parâmetros. Em C ++ (e provavelmente em dialetos C não padrão), você pode simplesmente omitir o nome do parâmetro, como este snippet C ++ (fácil de converter para C):No C padrão, com configurações de avisos comuns, o parâmetro não utilizado gera um aviso, que pode ser corrigido por uma instrução como a
(void)argc;
que faz com que o nome seja usado sem gerar nenhum código.argc
é bom ter, porque de outra forma muitos programas precisariam percorrer os parâmetros para obter a contagem. Além disso, em muitas linguagens de programação com arrays que têm comprimento, não existe nenhumargc
parâmetro, há apenas um array com os itens.fonte