From d1792eeea8d66d6bb5c9c07df9403d7ce445d357 Mon Sep 17 00:00:00 2001 From: Blau Araujo Date: Wed, 2 Apr 2025 11:23:52 -0300 Subject: [PATCH] =?UTF-8?q?Conte=C3=BAdo=20da=20aula=209?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- aulas/09-args/README.org | 163 +++++++++++++++++++++++++++++++++++++++ aulas/09-args/args.c | 22 ++++++ aulas/09-args/envp.c | 22 ++++++ aulas/09-args/exemplos.c | 33 ++++++++ aulas/09-args/getenv.c | 26 +++++++ aulas/09-args/strlist.c | 33 ++++++++ 6 files changed, 299 insertions(+) create mode 100644 aulas/09-args/README.org create mode 100644 aulas/09-args/args.c create mode 100644 aulas/09-args/envp.c create mode 100644 aulas/09-args/exemplos.c create mode 100644 aulas/09-args/getenv.c create mode 100644 aulas/09-args/strlist.c diff --git a/aulas/09-args/README.org b/aulas/09-args/README.org new file mode 100644 index 0000000..d58c76a --- /dev/null +++ b/aulas/09-args/README.org @@ -0,0 +1,163 @@ +#+title: Curso Básico da Linguagem C +#+subtitle: Aula 8: Argumentos e ambiente +#+author: Blau Araujo +#+startup: show2levels +#+options: toc:3 + +* Aula 8: Argumentos e ambiente + +[[][Vídeo desta aula]] + +** Vetores de strings + +#+begin_src c +char str[] = "banana"; +printf("Tamanho de str : %zu\n", sizeof(str)); // Imprime 7. +#+end_src + +O vetor =str= é do tipo "/array of char/", tem 7 elementos (=char[7]=) e seu +nome é o endereço do primeiro caractere. + +#+begin_src c +char *pstr = "cabana"; +printf("Tamanho de pstr: %zu\n", sizeof(pstr)); // Imprime 8. +#+end_src + +#+begin_quote +O operador =sizeof= avaliou 8 bytes porque é o tamanho de um endereço. +#+end_quote + +O ponteiro =pstr= é do tipo "/pointer to char/", não tem referência sobre +o tamanho da string e seu nome avalia o endereço do primeiro caractere. + +*** Vetores de "ponteiros" + +Embora a classificação popular induza enganos, um vetor de /ponteiros/ é, +na verdade, um ponteiro para vetores de um dado tipo: + +#+begin_src c +int d1[] = {1,2,3}; +int d2[] = {4,5,6}; +int d3[] = {7,8,9}; + +int *v[] = {d1, d2, d3}; + +printf("Tamanho de v : %zu\n", sizeof(v)); // Imprime 8. +printf("Tamanho de v[0]: %zu\n", sizeof(v[0])); // Imprime 24 (3*8). +printf("Tamanho de d1 : %zu\n", sizeof(d1)); // Imprime 12 (3*4). +#+end_src + +#+begin_quote +O operador =sizeof= avaliou 8 bytes porque é o tamanho de um endereço. +#+end_quote + +O tipo de =v= é =int *= porque os tipos de seus elementos serão interpretados +na compilação como "/pointer to int/", em vez de "/array of int/". + +Para receber esse tipo de vetor, o parâmetro dessa função teria que ser +decladado como... + +#+begin_src c +void print_arr(int *arr[], int size); +#+end_src + +Ou... + +#+begin_src c +void print_arr(int **arr, int size); +#+end_src + +*** Vetores de strings + +Vetores de strings são vetores de ponteiros: + +#+begin_src c +char *frutas[] = {"banana", "laranja", "abacate"}; + +printf("Tamanho de frutas : %zu\n", sizeof(frutas)); // Imprime 24 (3*8). +printf("Tamanho de frutas[0]: %zu\n", sizeof(frutas[0])); // Imprime 8. +#+end_src + +#+begin_quote +O operador =sizeof= avaliou 8 bytes porque é o tamanho de um endereço. +#+end_quote + +As strings literais são interpretadas como /"pointer to char"/ (=char *=). + +Numa função... + +#+begin_src c +void print_list(char **list); +#+end_src + +*** Vetor de strings terminado com NULL + +Os vetores de argumentos e de ambiente são vetores de strings terminados +com uma string nula (contendo apenas '\0'), o que pode ser representado por +=(void *)0= (ponteiro nulo) ou simplesmente =NULL=. + +Esta seria uma lista de strings terminada com =NULL=. + +#+begin_src c +char *frutas[] = {"banana", "laranja", "abacate", NULL}; + +int i = 0; +while (frutas[i]) { + printf("[%d] => %s\n", i, frutas[i]); + i++; + } +/* Imprime: + [0] => banana + [1] => laranja + [2] => abacate +*/ +#+end_src + +** Parâmetros da função 'main' + +As especificação dizem que a função =main= pode ser definida sem receber +nenhum parâmetro... + +#+begin_src c +int main(void) { /* ... */ } +#+end_src + +Ou com dois parâmetros: + +- *Primeiro parâmetro:* variável inteira para a quantidade de argumentos + (tipicamente =argc=). +- *Segundo parâmetro:* ponteiro para o endereço da lista de argumentos da linha do + comando (strings) que iniciou o programa (tipicamente =argv=). + + #+begin_src c + int main(int argc, char **argv) { /* ... */ } + #+end_src + + Em algumas implementações, a função =main= pode declarar um terceiro parâmetro + para receber a lista das variáveis exportadas para o ambiente do processo: + + #+begin_src c + int main(int argc, char **argv, char **envp) { /* ... */ } + #+end_src + + Mesmo que o terceiro parâmetro não seja declarado, o ambiente pode ser + acessado com a função =getenv= (=stdlib.h=) ou com o ponteiro global =environ=. + + +#+begin_src c +#include +#include + +// Para informar que 'environ' existe... +extern char **environ; + +int main(int argc, char **argv) { + + printf("environ[0] => %s\n", environ[0]); // Imprime: SHELL=/bin/bash + + char *env = getenv("SHELL"); + printf("getenv(\042SHELL\042) => %s\n", env); // Imprime: /bin/bash + + return 0; +} +#+end_src diff --git a/aulas/09-args/args.c b/aulas/09-args/args.c new file mode 100644 index 0000000..51f58be --- /dev/null +++ b/aulas/09-args/args.c @@ -0,0 +1,22 @@ +#include + + +void print_list(char *list[]) { + int i = 0; + while (list[i] != NULL) { + printf("[%d] => %s\n", i, list[i]); + i++; + } +} + + +int main(int argc, char **argv) { + + // O vetor de argumentos (argv) é um vetor de strings + // terminado com um ponteiro nulo (NULL)... + + print_list(argv); + + return 0; +} + diff --git a/aulas/09-args/envp.c b/aulas/09-args/envp.c new file mode 100644 index 0000000..cbb4293 --- /dev/null +++ b/aulas/09-args/envp.c @@ -0,0 +1,22 @@ +#include + + +void print_list(char *list[]) { + int i = 0; + while (list[i] != NULL) { + printf("[%d] => %s\n", i, list[i]); + i++; + } +} + + +int main(int argc, char **argv, char **envp) { + + // O vetor de ambiente (envp) é um vetor de strings + // terminado com um ponteiro nulo (NULL)... + + print_list(envp); + + return 0; +} + diff --git a/aulas/09-args/exemplos.c b/aulas/09-args/exemplos.c new file mode 100644 index 0000000..08a42f8 --- /dev/null +++ b/aulas/09-args/exemplos.c @@ -0,0 +1,33 @@ +#include + + +void print_list(char *list[]); + + +int main(void) { + /* + Os vetores de argumentos e de ambiente + são listas de strings terminadas com NULL: + + NULL = (void *)0 + */ + char *str_list[] = { + "banana", + "laranja", + "abacate", + NULL + }; + + print_list(str_list); + + return 0; +} + + +void print_list(char *list[]) { + int i = 0; + while (list[i]) { + printf("[%d] => %s\n", i, list[i]); + i++; + } +} diff --git a/aulas/09-args/getenv.c b/aulas/09-args/getenv.c new file mode 100644 index 0000000..2ca8a10 --- /dev/null +++ b/aulas/09-args/getenv.c @@ -0,0 +1,26 @@ +#include +#include + +void print_list(char *list[]) { + int i = 0; + while (list[i] != NULL) { + printf("[%d] => %s\n", i, list[i]); + i++; + } +} + +// Para informar que 'environ' existe... +extern char **environ; + +int main(int argc, char **argv) { + + print_list(environ); + + // printf("environ[0] => %p => %s\n", environ[0], environ[0]); + + // char *env = getenv("SHELL"); + // printf("getenv(\042SHELL\042) => %p => %s\n", env, env); + + return 0; +} + diff --git a/aulas/09-args/strlist.c b/aulas/09-args/strlist.c new file mode 100644 index 0000000..9815f13 --- /dev/null +++ b/aulas/09-args/strlist.c @@ -0,0 +1,33 @@ +#include + + +void print_list(char *list[]) { + int i = 0; + while (list[i] != NULL) { + printf("[%d] => %s\n", i, list[i]); + i++; + } +} + + +int main(void) { + + // Vetor de strings terminado com NULL... + + char *str[] = { + "banana", + "laranja", + "abacate", + (void *)0 /* NULL */ + }; + + print_list(str); + + // O vetor de argumentos (argv) é um vetor de strings + // terminado com um ponteiro nulo (NULL)... + + // print_list(envp); + + return 0; +} +