====== A função main ====== {{ progc_funcao_main.mkv |Video desta aula}} {{ main.png?100|https://www.redbubble.com/i/framed-print/T-Shirt-programmer-main-function-by-mohammedisoft/32698776.AJ1A3}}A função ''main'' é o local de início (//[[https://en.wikipedia.org/wiki/Entry_point#C_and_C++|entry point]]//) da execução de um código em C. Apesar de termos usado até o momento essa função sem parâmetros, ela possui alguns parâmetros que permitem a comunicação entre o programa em C e o //shell// do sistema operacional. ===== Protótipos ===== O protótipo da função ''main'' depende do sistema operacional subjacente: // padrão C ANSI int main (void) ; int main (int argc, char **argv) ; int main (int argc, char *argv[]) ; // sistemas UNIX-like (Linux, FreeBSD, Solaris, ...) e Windows int main (int argc, char **argv, char **envp) ; // sistemas Apple (MacOS, iOS) int main (int argc, char **argv, char **envp, char **apple) ; ===== Argumentos da linha de comando ===== Significado dos parâmetros usuais: * ''argc'': número de argumentos na linha de comando que lançou a execução; * ''argv'': vetor de strings (''char *'') contendo os argumentos da linha de comando, finalizado por um ponteiro nulo; * ''envp'': vetor de strings (''char *'') na forma "nome=valor" contendo as [[https://www.gnu.org/software/libc/manual/html_node/Environment-Variables.html|variáveis de ambiente]] exportadas pelo //shell// que lançou a execução do programa (também finalizado por um ponteiro nulo); O código a seguir imprime na tela os argumentos usados no lançamento do programa: #include int main (int argc, char **argv, char **envp) { int i ; printf ("Numero de argumentos: %d\n", argc) ; for (i = 0; i < argc; i++) printf ("argv[%d]: %s\n", i, argv[i]) ; return (0) ; } Um exemplo de compilação e execução do código acima: $ gcc argv.c -o argv -Wall $ ./argv teste 1 2 3 --help Numero de argumentos: 6 argv[0]: ./argv argv[1]: teste argv[2]: 1 argv[3]: 2 argv[4]: 3 argv[5]: --help ===== Funções específicas ===== Para ler e tratar mais facilmente as opções da linha de comando informadas por //argc/argv//, sugere-se usar funções já prontas para isso, como ''getopt'' ou ''arg_parse'' ([[https://www.gnu.org/software/libc/manual/html_node/Parsing-Program-Arguments.html#Parsing-Program-Arguments|link]]) Eis um exemplo de uso da função ''getopt'' para a leitura de opções da linha de comando, adaptado do [[https://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.html#Example-of-Getopt|manual da GNU-LibC]]: #include #include #include #include int main (int argc, char **argv) { int flag_a = 0; int flag_b = 0; char *value_c = NULL; int option; opterr = 0; // options: -a, -b, -c value (defined by "abc:") while ((option = getopt (argc, argv, "abc:")) != -1) switch (option) { case 'a': // option -a was set flag_a = 1; break; case 'b': // option -b was set flag_b = 1; break; case 'c': // option -c was set with value value_c = optarg; break; default: fprintf (stderr, "Usage: %s -a -b -c value\n", argv[0]); exit (1) ; } printf ("flag_a = %d, flag_b = %d, value_c = %s\n", flag_a, flag_b, value_c); return 0; } ===== Status de saída ===== Outro canal de interação importante entre o programa C e o sistema operacional é o valor de retorno da função ''main'', que é devolvido ao SO após a execução na forma de um //status// de saída (//exit status//). #include int main (int argc, char **argv, char **envp) { return (14) ; } O //status// de saída de um processo pode ser consultado no terminal UNIX (shell Bash) através da variavel ''$?'' disponível no shell: $ gcc retval.c -o retval -Wall $ ./retval $ echo $? 14 O status de saída também pode ser usado em scripts do shell: #!/bin/sh if retval then # exit status is zero echo "true" else # exit status is NOT zero echo "false" fi ===== Exercícios ===== - Escrever um programa que recebe uma lista de parâmetros na linha de comando. Ele não escreve nada na saída, mas devolve como //status// de saída o número de parâmetros que iniciam com o caractere "''-''". - Escrever um programa ''exists'', que recebe um nome (ou caminho) de arquivo na linha de comando e devolve, no //status// de saída, 0 se o arquivo existe ou 1 se ele não existe. - Escrever um programa para listar as variáveis de ambiente recebidas pelo programa (parâmetro ''envp'' da função ''main''); essas variáveis podem ser consultadas no terminal (//shell//) através do comando ''env''.