forked from blau_araujo/cblc
"Exercícios aulas 3 e 4"
This commit is contained in:
parent
3188fe3d4a
commit
c9b64fbaf4
16 changed files with 322 additions and 0 deletions
19
aulas/09-args/lab
Normal file
19
aulas/09-args/lab
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
Laboratório Relâmpago
|
||||||
|
O laboratório relâmpago é uma metodologia desenvolvida pelo Instituto Procomum. Sua
|
||||||
|
utilização prevê induzir a criação de comunidades de prática temáticas e/ou territoriais.
|
||||||
|
Consiste em uma chamada pública destinada a selecionar pessoas interessadas em um
|
||||||
|
determinado assunto, que tenham ou não uma ideia a desenvolver. A partir do chamamento,
|
||||||
|
seleciona-se um grupo diverso, levando em conta aspectos de classe, gênero, raça, formação
|
||||||
|
e escolaridade.
|
||||||
|
Esse grupo é reunido em uma oficina que pode durar um dia ou um fim de semana inteiro.
|
||||||
|
Nessa oficina, os facilitadores expõem o problema e também eventuais formas de
|
||||||
|
solucioná-lo. O assunto é de domínio dos participantes e a troca de conhecimentos dita o
|
||||||
|
ritmo do diálogo. Durante a oficina, o grupo escolhe, entre ideias expostas por seus
|
||||||
|
membros, de três a cinco iniciativas para serem prototipadas.
|
||||||
|
Ou seja, rapidamente (daí o nome), formam-se grupos de colaboração em torno de uma
|
||||||
|
possível solução para o problema. Esses grupos recebem uma bolsa em dinheiro e recursos
|
||||||
|
não monetários e passam a ter entre duas e quatro semanas para desenvolver o protótipo. Os
|
||||||
|
resultados são apresentados em uma nova oficina, seguida de celebração.
|
||||||
|
Além de protótipos, o laboratório relâmpago gera, como impacto, a formação de uma
|
||||||
|
comunidade em torno de um problema. Essas comunidades tendem a ser atuantes enquanto
|
||||||
|
o problema não for solucionado.
|
13
exercicios/03/1_pesquise_demonstre.c
Normal file
13
exercicios/03/1_pesquise_demonstre.c
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
unsigned long quadrado(long base) {
|
||||||
|
printf("O tamanho do tipo de base * base é %zu bytes\n", sizeof(base * base));
|
||||||
|
return base * base; /* Qual é o tipo desse expressão? */
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
int num = 5;
|
||||||
|
|
||||||
|
printf("%d^2 = %ld\n", num, quadrado(num));
|
||||||
|
return 0;
|
||||||
|
}
|
12
exercicios/03/2fahr_celsius.c
Normal file
12
exercicios/03/2fahr_celsius.c
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
//c = 5 * (f - 32) / 9
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
float c;
|
||||||
|
for (int i = -100; i <= 100; i++) {
|
||||||
|
c = 5 * (i - 32) /9;
|
||||||
|
printf("Fahr: %d, Celsius %2f\n", i, c);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
18
exercicios/03/3pesquise_responda.md
Normal file
18
exercicios/03/3pesquise_responda.md
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# O operador _sizeof(TIPO)_ expressa o tamanho em bytes de _TIPO_ com o tipo _size_t_
|
||||||
|
|
||||||
|
## O que é o tipo _size_t_?
|
||||||
|
|
||||||
|
É usado para a contagem de bytes. É o resultado do operador _sizeof_. É um inteiro sem sinal capaz de armazenar valores [0, SIZE_MAX].
|
||||||
|
|
||||||
|
## Como utilizá-lo no seu programa sem incluir cabeçalhos?
|
||||||
|
|
||||||
|
Utilizando typedef, mas não é recomendado.
|
||||||
|
|
||||||
|
## Em quais cabeçalhos ele é definido?
|
||||||
|
Em <stddef.h>, mas também em <aio.h>, <glob.h>, <grp.h>, <iconv.h>, <monetary.h>, <mqueue.h>, <ndbm.h>, <pwd.h>, <regex.h>, <search.h>, <signal.h>, <stdio.h>, <stdlib.h>, <string.h>, <strings.h>, <sys/mman.h>, <sys/msg.h>, <sys/sem.h>, <sys/shm.h>, <sys/socket.h>, <sys/types.h>, <sys/uio.h>, <time.h>, <unistd.h>, <wchar.h>, and <wordexp.h>.
|
||||||
|
|
||||||
|
## Qual é o especificador de formatos para ele no _printf_ ?
|
||||||
|
|
||||||
|
%zu e %zx
|
||||||
|
|
||||||
|
|
39
exercicios/03/4comp_corrija_resp.md
Normal file
39
exercicios/03/4comp_corrija_resp.md
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
## O programa abaixo deveria imprimir 0.25 no terminal...
|
||||||
|
|
||||||
|
~~~C
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
int valor = 1 / 4;
|
||||||
|
|
||||||
|
printf("%d\n", valor);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
~~~
|
||||||
|
|
||||||
|
### Depois de compilado e executado, qual foi o valor impresso?
|
||||||
|
0
|
||||||
|
|
||||||
|
### Porque isso aconteceu?
|
||||||
|
|
||||||
|
o valor foi truncado pois a variável foi declarada e especificada como um inteiro.
|
||||||
|
|
||||||
|
### Como solucionar?
|
||||||
|
|
||||||
|
Basta declarar valor como _float_ e utilizar a formatação de tipos adequada.
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
float valor = 1 / 4;
|
||||||
|
|
||||||
|
printf("%f\n", valor);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
39
exercicios/03/5dump.c
Normal file
39
exercicios/03/5dump.c
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void print_bytes(char *label, void *addr, size_t size);
|
||||||
|
// declaração do protótipo
|
||||||
|
int main(void) {
|
||||||
|
|
||||||
|
int num = 100000;
|
||||||
|
// declaração da variável num como valor inteiro
|
||||||
|
int sqr_int = num * num;
|
||||||
|
// inicializa o inteiro sqr_int como num multiplicado por num
|
||||||
|
unsigned long sqr_long = (unsigned long)num * num;
|
||||||
|
// atribui sqr long como tipo long, garantindo sua tipagem correta com o parentesis
|
||||||
|
print_bytes("num ", &num, sizeof(num));
|
||||||
|
printf("-> %d\n", num);
|
||||||
|
//utiliza o protótipo para imprimir o endereço na memória e bytes á byte do dado
|
||||||
|
//utiliza o printf para imprimir o valor literal da variável
|
||||||
|
print_bytes("sqr_int ", &sqr_int, sizeof(sqr_int));
|
||||||
|
printf("-> %d\n", sqr_int);
|
||||||
|
|
||||||
|
print_bytes("sqr_long", &sqr_long, sizeof(sqr_long));
|
||||||
|
printf("-> %lu\n", sqr_long);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void print_bytes(char *label, void *addr, size_t size) {
|
||||||
|
//cria o protótipo contador de bytes, utilizando um ponteiro para char, um ponteiro para endereço e o especificador size_t
|
||||||
|
unsigned char *bytes = (unsigned char *)addr;
|
||||||
|
//declara o ponteiro bytes como unsigned char e o inicializa em addr
|
||||||
|
printf("%p - %s - ", bytes, label);
|
||||||
|
// utiliza o printf para impŕimir o endereço dos bytes e o tipo enunciado
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 8; i++)
|
||||||
|
printf("%02x ", i > (size - 1) ? 0 : bytes[i]);
|
||||||
|
}
|
||||||
|
//criar um loop que percorre byte a byte a variável declarada até o valor 8 de size_t, imprimi todos os indices do item byte
|
||||||
|
//
|
||||||
|
|
BIN
exercicios/03/a.out
Executable file
BIN
exercicios/03/a.out
Executable file
Binary file not shown.
49
exercicios/03/pbytesdaniel.c
Normal file
49
exercicios/03/pbytesdaniel.c
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
// versão do colega Daniel, publicada no Issues
|
||||||
|
//
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void print_bytes(char *label, void *addr, size_t size);
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
|
||||||
|
int num = 100000;
|
||||||
|
int sqr_int = num * num;
|
||||||
|
unsigned long sqr_long = (unsigned long)num * num;
|
||||||
|
//--------------
|
||||||
|
print_bytes("---------------> num", &num, sizeof(num));
|
||||||
|
printf("Resultado -> %d\n", num);
|
||||||
|
|
||||||
|
print_bytes("-----------> sqr_int", &sqr_int, sizeof(sqr_int));
|
||||||
|
printf("Resultado -> %d\n", sqr_int);
|
||||||
|
|
||||||
|
print_bytes("----------> sqr_long", &sqr_long, sizeof(sqr_long));
|
||||||
|
printf("Resultado -> %lu\n", sqr_long);
|
||||||
|
//--------------
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_bytes(char *label, void *addr, size_t size) {
|
||||||
|
|
||||||
|
unsigned char *bytes = (unsigned char *)addr;
|
||||||
|
|
||||||
|
//printf("%p - %s - ", bytes, label);
|
||||||
|
//printf("%p - %s\n", bytes, label);
|
||||||
|
printf("%s - %p\n", label, bytes);
|
||||||
|
|
||||||
|
// Se a avaliação da expressão 'i > (size -1)' retornar 0 (falso),
|
||||||
|
// ela receberá o valor que vem depois dos ':' que é o valor
|
||||||
|
// apontado por bytes[i].
|
||||||
|
//
|
||||||
|
// Se a avaliação da expressão 'i > (size -1)' retornar 1 (verdadeiro).
|
||||||
|
// ela receberá o valor que vem depois da '?'
|
||||||
|
// == 0 falso
|
||||||
|
// != 0 verdadeiro
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 8; i++) {
|
||||||
|
int res = i > (size - 1);
|
||||||
|
printf("| Endereço do byte[i]: %p | Retorno de [i]: %d ", &bytes[i], res);
|
||||||
|
printf("| Valor no byte: %02x |\n", i > (size - 1) ? 0 : bytes[i]);
|
||||||
|
//printf("|>Retorno de [i]: %d : Endereço do Byte[i]: %p<| \n", res, &bytes[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
BIN
exercicios/04/.5quad_numero.c.swp
Normal file
BIN
exercicios/04/.5quad_numero.c.swp
Normal file
Binary file not shown.
26
exercicios/04/1pesquise_responda.md
Normal file
26
exercicios/04/1pesquise_responda.md
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
## Existe uma forma para alterar uma variável em uma função a partir de outra função? Como fazer isso?
|
||||||
|
Acredito que é possível utilizar o escopo das variáveis para determinar a melhor escolha. Para alguns casos é possível utilizar o escopo global da variável (ser declarada fora das funções).
|
||||||
|
|
||||||
|
Também temos o recurso _extern_, mais utilizado para programas com mais de um arquivo de código, explicado no livro C Programming Language, ainda no primeiro caṕítulo.
|
||||||
|
|
||||||
|
Podemos fazer também a passagem por referência, utilizando ponteiros. (Cap 5 C Programming Language).
|
||||||
|
|
||||||
|
## Porque as variáveis de uma função, em princípio, são locais à própria função?
|
||||||
|
|
||||||
|
Acredito que primeiramente seja uma escolha na estruturação da própria linguagem C. Uma linguagem simples, estruturada, que é explicíta e que exige comprometimento do programador.
|
||||||
|
Esta escolha permite ao programador maior controle do seu código e evita erros e problemas em programas mais longos.
|
||||||
|
Tudo isto reflete a filosofia da linguagem e facilita a vida do programador: permite a utilização do mesmo nome de variável, ajuda para encontrar erros, debug, encapsulamento/estruturação de código personalizável, evita erros e variações indesejadas com as variáveis.
|
||||||
|
|
||||||
|
## Se o valor associado a um ponteiro é um endereço, o que teremos com a avaliação de _&NOME_DO_PONTEIRO_?
|
||||||
|
Ponteiro são variáveis, portanto, teremos o endereço de memória onde variável ponteiro está armazenada.
|
||||||
|
|
||||||
|
~~~C
|
||||||
|
#include <stdio.h>
|
||||||
|
//ponteiro não inicializado
|
||||||
|
int main() {
|
||||||
|
int *ponteiro;
|
||||||
|
printf(format: "%p\n", (void*)&ponteiro);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
~~~
|
||||||
|
|
21
exercicios/04/2analise.md
Normal file
21
exercicios/04/2analise.md
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
## Pesquise e responda
|
||||||
|
|
||||||
|
Este é mais um "Olá, mundo":
|
||||||
|
|
||||||
|
~~~C
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
char *msg = "Salve, simpatia!";
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
puts(msg);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
~~~
|
||||||
|
|
||||||
|
### Se ponteiros recebem endereços como valores, por que eu fiz a atribuição de uma string e o meu programa funcionou?
|
||||||
|
|
||||||
|
Strings literais em C são armazenadas como arrays de caracteres na memória, terminados em _\0_. _msg_ recebe o endereço do primeiro caractere e _puts_ percorre o endereço até encontrar _\0_.
|
30
exercicios/04/3comp_analise_demo.c
Normal file
30
exercicios/04/3comp_analise_demo.c
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
|
||||||
|
int a = 0;
|
||||||
|
int b = 875569217;
|
||||||
|
int c = 1280655661;
|
||||||
|
int d = 1129071171;
|
||||||
|
|
||||||
|
char *p = (char *)&d;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while (*(p + i) != '\0') {
|
||||||
|
putchar(*(p + i));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
putchar('\n');
|
||||||
|
|
||||||
|
printf("%p\n%p\n%p\n%p\n", &d, &c, &b, &a);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//Como o código funciona?
|
||||||
|
//Declara variáveis de números inteiros
|
||||||
|
//cria um ponteiro para char que resulta em um endereço na memória &d
|
||||||
|
//
|
||||||
|
//O que estou tentando imprimir?
|
||||||
|
//
|
||||||
|
//CBLC
|
||||||
|
|
30
exercicios/04/4pesquise_responda.md
Normal file
30
exercicios/04/4pesquise_responda.md
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
## Para que serve e como usar a função _putchar_?
|
||||||
|
Escreve um caractere na saída padrão.
|
||||||
|
Podemos declarar uma variável _char_ com aspas simples e um caractere e depois utilizar a função:
|
||||||
|
~~~C
|
||||||
|
char a = 'b';
|
||||||
|
putchar(a);
|
||||||
|
//saída: b
|
||||||
|
~~~
|
||||||
|
Ou simplesmente utilizar a função com um caractere simples em aspas simples:
|
||||||
|
~~~C
|
||||||
|
putchar('b');
|
||||||
|
//saída: b
|
||||||
|
~~~
|
||||||
|
|
||||||
|
## Quando e por que utilizar _putchar('\n')_ em vez de _puts("")_?
|
||||||
|
|
||||||
|
_putchar_ parece mais conveniente quando desejamos fazer algum tipo de conversão ou alteração do caractere, pois ele retorna o caractere escrito como um caractere sem sinal que sofreu cast/conversão para inteiro (man 3 putchar);
|
||||||
|
|
||||||
|
e _puts_ quando precisamos somente de um número não negativo como sucesso.
|
||||||
|
|
||||||
|
## Como funciona a estrutura de repetição _while_?
|
||||||
|
|
||||||
|
Trata-se de um estrutura que pode ser executada a partir ou até uma condição delimitada pelo programador. Ele faz um teste para iniciar a operação lógica e quando verdadeira a executa até ser falsa ou a condição lógica para o seu término.
|
||||||
|
|
||||||
|
## Para que servem os especificadores de formato _%zu_ e _%p_?
|
||||||
|
|
||||||
|
_%zu_ é o especificador de formato para _size_t_, um tipo de dado utilizado para representar tamanhos de objetos.
|
||||||
|
_%p_ é o especificador de formato que imprime o endereço de memória de uma variável ponteiro. O valor é exibido em hexadecimal.
|
||||||
|
|
||||||
|
|
19
exercicios/04/5quad_numero.c
Normal file
19
exercicios/04/5quad_numero.c
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
int a;
|
||||||
|
printf("Digite um número inteiro para cálculo do seu quadrado:\n");
|
||||||
|
|
||||||
|
if (scanf("%d", &a)) {
|
||||||
|
a > 0 && a > INT_MAX && a * a > INT_MAX;
|
||||||
|
fprintf(stderr, "Não é um inteiro válido\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
int quad = a * a;
|
||||||
|
printf("O quadrado do número é %d\n", quad);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
BIN
exercicios/04/a.out
Executable file
BIN
exercicios/04/a.out
Executable file
Binary file not shown.
7
exercicios/04/nomedoponteiro.c
Normal file
7
exercicios/04/nomedoponteiro.c
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
//ponteiro não inicializado
|
||||||
|
int main() {
|
||||||
|
int *ponteiro;
|
||||||
|
printf("%p\n", (void*)&ponteiro);
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue