Conteúdo da aula 9

This commit is contained in:
Blau Araujo 2025-04-02 11:23:52 -03:00
parent c503851e31
commit d1792eeea8
6 changed files with 299 additions and 0 deletions

163
aulas/09-args/README.org Normal file
View file

@ -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 <stdio.h>
#include <stdlib.h>
// 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

22
aulas/09-args/args.c Normal file
View file

@ -0,0 +1,22 @@
#include <stdio.h>
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;
}

22
aulas/09-args/envp.c Normal file
View file

@ -0,0 +1,22 @@
#include <stdio.h>
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;
}

33
aulas/09-args/exemplos.c Normal file
View file

@ -0,0 +1,33 @@
#include <stdio.h>
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++;
}
}

26
aulas/09-args/getenv.c Normal file
View file

@ -0,0 +1,26 @@
#include <stdio.h>
#include <stdlib.h>
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;
}

33
aulas/09-args/strlist.c Normal file
View file

@ -0,0 +1,33 @@
#include <stdio.h>
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;
}