Quais são os valores finais de a, b, tmp? (O que isso está fazendo?)
tmp=3 (salva o valor original de a) → a=5 (copia b em a) → b=3 (copia tmp de volta para b) Resposta: a=5, b=3, tmp=3 Esse é o padrão clássico de troca de valores.
T-04Variável
int a = 10;
int b = a / 3;
int c = a % 3;
double d = (double)a / 3;
Quais são os valores de b, c, d?
b = 10/3 = 3 (divisão inteira trunca) c = 10%3 = 1 (resto) d = 10.0/3 = 3.333... (o cast promove para divisão em double) Resposta: b=3, c=1, d=3.333333
T-05Variável
int a = 1;
a += a++; // aviso de comportamento indefinidoprintf("%d\n", a);
Qual é a saída? Dica: é uma questão "pegadinha".
Isso é comportamento indefinido. Modificar e ler a mesma variável em uma única expressão não é garantido pelo padrão C. Compiladores diferentes podem produzir 2, 3 ou outros resultados. Lição: Nunca misture ++ e atribuição na mesma variável em uma única expressão.
T-06Variável
int i = 0, sum = 0;
while (i < 5) {
sum += i;
i++;
}
Rastreie i e sum após cada iteração do laço em uma tabela.
Iter
i (antes)
sum += i
após i++
1
0
0+0=0
1
2
1
0+1=1
2
3
2
1+2=3
3
4
3
3+3=6
4
5
4
6+4=10
5
Resposta: i=5, sum=10 (0+1+2+3+4)
T-07Variável
int n = 12345, rev = 0;
while (n > 0) {
rev = rev * 10 + n % 10;
n /= 10;
}
Rastreie n e rev após cada iteração. O que este programa faz?
Iter
n%10
rev
n
1
5
0*10+5=5
1234
2
4
5*10+4=54
123
3
3
54*10+3=543
12
4
2
543*10+2=5432
1
5
1
5432*10+1=54321
0
Resposta: n=0, rev=54321 Este programa inverte os dígitos de um inteiro.
int a[4] = {10, 20, 30, 40};
for (int i = 0; i < 3; i++) {
a[i] = a[i + 1];
}
Qual é o estado final de a? O que este código faz?
i=0: a[0]=a[1] → {20,20,30,40} i=1: a[1]=a[2] → {20,30,30,40} i=2: a[2]=a[3] → {20,30,40,40} Resposta: {20, 30, 40, 40} Isso remove o primeiro elemento deslocando todos para a esquerda (o último elemento fica duplicado).
T-10Vetor
int a[5] = {2, 8, 3, 9, 1};
int max = a[0], idx = 0;
for (int i = 1; i < 5; i++) {
if (a[i] > max) {
max = a[i];
idx = i;
}
}
Rastreie como max e idx mudam a cada passo.
i
a[i]
a[i]>max?
max
idx
init
-
-
2
0
1
8
8>2 Sim
8
1
2
3
3>8 Não
8
1
3
9
9>8 Sim
9
3
4
1
1>9 Não
9
3
Resposta: max=9, idx=3
T-11Vetor
int a[5] = {5, 3, 8, 1, 4};
// Primeira passada do bubble sort (levando o mínimo para o começo)for (int j = 4; j > 0; j--) {
if (a[j-1] > a[j]) {
int tmp = a[j-1]; a[j-1] = a[j]; a[j] = tmp;
}
}
Rastreie o estado do vetor depois de uma passada.
Inicial: {5,3,8,1,4} j=4: a[3]>a[4]? 1>4 Não → {5,3,8,1,4} j=3: a[2]>a[3]? 8>1 Sim → {5,3,1,8,4} j=2: a[1]>a[2]? 3>1 Sim → {5,1,3,8,4} j=1: a[0]>a[1]? 5>1 Sim → {1,5,3,8,4} Resposta: {1, 5, 3, 8, 4} (o valor mínimo 1 borbulha até o começo)
T-12Vetor
int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
int sum = 0;
for (int i = 0; i < 3; i++) {
sum += a[i][i];
}
Qual é o valor de sum? O que isso calcula?
a[0][0]=1, a[1][1]=5, a[2][2]=9 sum = 1+5+9 = 15 Isso calcula o traço de uma matriz (soma dos elementos da diagonal principal).
Rastreando Ponteiros
T-13Ponteiro
int a = 10, b = 20;
int *p = &a;
*p = 30;
p = &b;
*p = *p + 5;
int a = 5, b = 10;
int *p = &a, *q = &b;
*p = *q;
*q = 0;
printf("%d %d\n", a, b);
Qual é a saída?
*p=*q → a=10 (copia o valor de b para a) *q=0 → b=0 Resposta: 10 0
T-15Ponteiro
int arr[4] = {10, 20, 30, 40};
int *p = arr;
printf("%d ", *p);
p += 2;
printf("%d ", *p);
printf("%d ", *(p - 1));
printf("%d\n", p[1]);
Qual é a saída?
p=arr → *p=10 p+=2 → p aponta para arr[2] → *p=30 *(p-1)=arr[1]=20 p[1]=*(p+1)=arr[3]=40 Resposta: 10 30 20 40
T-16Ponteiro
int arr[5] = {1, 2, 3, 4, 5};
int *p = arr + 1;
int *q = arr + 3;
printf("%d %d %ld\n", *p, *q, q - p);
Qual é a saída?
p=&arr[1] → *p=2 q=&arr[3] → *q=4 q-p = 3-1 = 2 (diferença em número de elementos) Resposta: 2 4 2
T-17Ponteiro
int x = 100;
int *p = &x;
int **pp = &p;
**pp = 200;
printf("%d %d %d\n", x, *p, **pp);
Qual é a saída? (Ponteiro duplo)
Cadeia pp → p → x. **pp=200 modifica x para 200. x=200, *p=200, **pp=200 (todos se referem ao mesmo local) Resposta: 200 200 200
T-18Ponteiro
int a[] = {10, 20, 30, 40, 50};
int *p = a;
for (int i = 0; i < 5; i++) {
*(p + i) *= 2;
}
Qual é o estado final de a?
Dobra cada elemento: {20, 40, 60, 80, 100} *(p+i) é equivalente a a[i]. Manipulação do vetor via aritmética de ponteiros.
Rastreando Chamadas de Função
T-19Função
voidadd_ten(int x) { x += 10; }
intmain(void) {
int a = 5;
add_ten(a);
printf("%d\n", a);
}
Qual é a saída?
Resposta: 5 O C usa passagem por valor. O x dentro de add_ten é uma cópia de a, então modificar x não afeta a.
T-20Função
voidadd_ten(int *px) { *px += 10; }
intmain(void) {
int a = 5;
add_ten(&a);
printf("%d\n", a);
}
Qual é a saída? (Compare com T-19.)
Resposta: 15 Como passamos um ponteiro, *px += 10 modifica o próprio a.
T-21Função
intmystery(int a, int b) {
a = a + b;
b = a - b;
a = a - b;
return a * 10 + b;
}
printf("%d\n", mystery(3, 7));
Qual é a saída? Rastreie a e b linha por linha.
a=3, b=7 a=3+7=10 b=10-7=3 a=10-3=7 return 7*10+3 = 73 Isso é uma troca sem variável temporária. a e b são trocados, então o resultado é 7*10+3=73.
T-22Função
voidmodify(int arr[], int n) {
for (int i = 0; i < n; i++) arr[i] *= 3;
}
intmain(void) {
int data[] = {1, 2, 3};
modify(data, 3);
printf("%d %d %d\n", data[0], data[1], data[2]);
}
Qual é a saída? (Passagem de vetor vs. passagem de int)
Resposta: 3 6 9 Vetores são passados como ponteiros, então modificações dentro da função afetam o chamador. Isso é diferente da passagem por valor de ints (T-19)!
T-23Função
intfactorial(int n) {
if (n <= 1) return1;
return n * factorial(n - 1);
}
printf("%d\n", factorial(5));
Rastreie a expansão e o retorno da pilha de chamadas.
int a[3] = {1, 2, 3};
int *p = a;
for (int i = 0; i < 3; i++) {
a[i] = a[(2-i)];
}
Qual é o estado final de a? (Dica: NÃO vira um vetor invertido. Por quê?)
i=0: a[0]=a[2] → {3,2,3} i=1: a[1]=a[1] → {3,2,3} i=2: a[2]=a[0] → {3,2,3} (a[0] já é 3!) Resposta: {3, 2, 3} (NÃO {3, 2, 1}) Motivo: As iterações anteriores sobrescrevem o começo do vetor, então leituras posteriores pegam valores já modificados. Uma inversão correta precisa de um vetor temporário ou uma troca com dois ponteiros.
T-30Misto
intf(int *a, int *b) {
*a += *b;
*b = *a - *b;
return *a + *b;
}
intmain(void) {
int x = 4, y = 6;
int z = f(&x, &y);
printf("%d %d %d\n", x, y, z);
}
Qual é a saída? (Rastreie modificações via ponteiros.)
int a[5] = {5, 2, 8, 1, 9};
for (int i = 0; i < 4; i++) {
if (a[i] > a[i+1]) {
int t = a[i]; a[i] = a[i+1]; a[i+1] = t;
}
}
Qual é o estado final de a? O que está garantido sobre ele?
i=0: 5>2 → troca → {2,5,8,1,9} i=1: 5>8? Não → {2,5,8,1,9} i=2: 8>1 → troca → {2,5,1,8,9} i=3: 8>9? Não → {2,5,1,8,9} Resposta: {2, 5, 1, 8, 9} Está garantido que o valor máximo (9) termina na última posição (uma passagem de bubble sort varrendo para frente).
T-32Misto
intcount = 0;
for (int i = 1; i <= 100; i++) {
if (i % 3 == 0 && i % 5 == 0)
count++;
}
Qual é o valor final de count? (Não precisa rastrear tudo — ache o padrão.)
Divisíveis por 3 e por 5 → conta os múltiplos de 15. Múltiplos de 15 entre 1..100: 15, 30, 45, 60, 75, 90 — 6 valores. Resposta: count=6
intgcd(int a, int b) {
while (b != 0) {
int tmp = b;
b = a % b;
a = tmp;
}
return a;
}
printf("%d\n", gcd(48, 18));
Rastreie a, b e tmp em cada iteração.
Iter
a
b
tmp
a%b
1
48
18
18
48%18=12
2
18
12
12
18%12=6
3
12
6
6
12%6=0
fim
6
0
-
-
Resposta: 6 (o maior divisor comum de 48 e 18)
T-38Misto
int *p = (int *)malloc(sizeof(int) * 3);
p[0] = 10; p[1] = 20; p[2] = 30;
int *q = p;
free(p);
// printf("%d\n", *q); ← isso é seguro?
O que acontece se acessarmos *q após free?
Comportamento indefinido (ponteiro solto). q estava apontando para o mesmo local que p, mas free(p) liberou aquela memória. q ainda guarda o mesmo endereço, mas a memória não é mais válida. Lição: Depois do free, defina também todos os ponteiros relacionados como NULL.
T-39Misto
int a[4] = {10, 20, 30, 40};
int *p = a, *q = a + 3;
while (p < q) {
int t = *p; *p = *q; *q = t;
p++; q--;
}
Qual é o estado final de a? O que está fazendo?
Iter 1: p=a[0], q=a[3] → troca(10,40) → {40,20,30,10}, p++, q-- Iter 2: p=a[1], q=a[2] → troca(20,30) → {40,30,20,10}, p++, q-- p>=q → sai Resposta: {40, 30, 20, 10} Isso é uma inversão in-place do vetor. Troca das duas pontas em direção ao centro.
T-40Misto
intbinary_search(int a[], int n, int key) {
int lo = 0, hi = n - 1;
while (lo <= hi) {
int mid = (lo + hi) / 2;
if (a[mid] == key) return mid;
else if (a[mid] < key) lo = mid + 1;
else hi = mid - 1;
}
return -1;
}
// a = {2, 5, 8, 12, 16, 23, 38, 56}, key = 23
Rastreie lo, hi, mid e diga em quantas iterações a chave é encontrada.