Programação de Computadores IIsimone/progII/contaulas/aula16.pdf · Programação de Computadores...

Preview:

Citation preview

Programação de Computadores IIAula 16. Ponteiros II

Slides cedidos por Karina Mochetti

2018.1

Aula 16. Ponteiros II

Exercício Aula Passada

Qual a diferença entre os dois códigos abaixo?

char* str = "Hello World";

for (int i = 0; i < strlen(str); i++)

printf("%c", str[i]);

char* str = "Hello World";

for (; *str != '\0'; str++)

printf("%c", *str);

Ambos imprimirão a mesma coisa na tela!!!

Aula 16. Ponteiros II

Endereço e Ponteiro

Endereço

Ao colocarmos o símbolo & temos o endereço daquela variável.

Ponteiro

Ao colocarmos o símbolo * temos o valor da variável armazenada

num determinado endereço.

int *p;

int n=0;

p = &n;

0x003A4581: 0x003A4585 p

0x003A4585: 0x00000000 n

p

0x003A4589: 0x19374998

O valor de n eh: 0x00000000O endereço de n é: 0x003A4585O valor de *n é: ERRORO valor de p é: 0x003A4585O endereço de p é: 0x003A4581O valor de *p é: 0x00000000

Aula 16. Ponteiros II

Endereço e Ponteiro

Ponteiros e endereços são sempre utilizados juntos.

Aula 16. Ponteiros II

Registro

typedef struct aluno {

int matricula;

float nota;

char nome[50];

} Aluno;

int main() {

Aluno a;

Aluno *p;

p = &a;

return 0;

}

A variável p terá o tamanho de um endereço de memória (4

bytes).

A região apontada por p terá o tamanho do tipo Aluno (58

bytes).Aula 16. Ponteiros II

Registro

typedef struct aluno {

int matricula;

float nota;

char nome[50];

} Aluno;

int main() {

Aluno a;

Aluno *p;

p = &a;

return 0;

}

Aula 16. Ponteiros II

Registro

typedef struct aluno {

int matricula;

float nota;

char nome[50];

} Aluno;

int main() {

Aluno a;

Aluno *p;

p = &a;

return 0;

}

A variável nome terá o mesmo tamanho da variável p, o

tamanho de um endereço de memória.

Aula 16. Ponteiros II

Registro

typedef struct aluno {

int matricula;

float nota;

char nome[50];

} Aluno;

int main() {

Aluno a;

Aluno *p;

p = &a;

(*p).nota = 10;

p->nota = 10;

a.nota = 10;

return 0;

}

(*p).nome é equivalente a p->nome.

Aula 16. Ponteiros II

Ponteiro para Ponteiro

int main() {

int a = 10;

int *p, **q, ***r;

p = &a;

q = &p;

r = &q;

printf("O endereco de r é %d", &r);

printf("O valor de r é %d", r);

printf("O valor de *r é %d", *r);

printf("O valor de **r é %d", **r);

printf("O valor de ***r é %d", ***r);

return 0;

}

O endereco de r é 0x005D334AF

O valor de r é 0x005D334AB

O valor de *r é 0x005D334A7

O valor de **r é 0x005D334A3

O valor de ***r é 10

Aula 16. Ponteiros II

Segmentation Fault

Normalmente ocorrem quando há a tentativa de acessar uma região

de memória que o programa não tem acesso.

int main() {

int a = 10, b = 20;

int *p, *q;

p = &a;

*q = 10;

q = &b;

*p = 15;

p = &a;

return 0;

}

Aula 16. Ponteiros II

Segmentation Fault

Normalmente ocorrem quando há a tentativa de acessar uma região

de memória que o programa não tem acesso.

int main() {

int a = 10, b = 20;

int *p, *q;

p = &a;

*q = 10;

q = &b;

*p = 15;

p = &a;

return 0;

}

Aula 16. Ponteiros II

Segmentation Fault

Normalmente ocorrem quando há a tentativa de acessar uma região

de memória que o programa não tem acesso.

int main() {

int a = 10, b = 20;

int *p, *q;

p = &a;

q = NULL;

*q = 10;

q = &b;

*p = 15;

p = &a;

return 0;

}

Aula 16. Ponteiros II

Segmentation Fault

Normalmente ocorrem quando há a tentativa de acessar uma região

de memória que o programa não tem acesso.

int main() {

int a = 10, b = 20;

int *p, *q;

p = &a;

q = &b;

*q = 10;

*p = 15;

p = &a;

return 0;

}

Aula 16. Ponteiros II

Segmentation Fault

Normalmente ocorrem quando há a tentativa de acessar uma região

de memória que o programa não tem acesso.

int main() {

char* str1, str2, str3;

str1 = "Hello World";

str2 = "Hello";

printf("%c", str1[0]);

printf("%c", str2[0]);

printf("%c", str3[0]);

return 0;

}

Aula 16. Ponteiros II

Segmentation Fault

Normalmente ocorrem quando há a tentativa de acessar uma região

de memória que o programa não tem acesso.

int main() {

char* str1, str2, str3;

str1 = "Hello World";

str2 = "Hello";

printf("%c", str1[0]);

printf("%c", str2[0]);

printf("%c", str3[0]);

return 0;

}

Aula 16. Ponteiros II

Segmentation Fault

Normalmente ocorrem quando há a tentativa de acessar uma região

de memória que o programa não tem acesso.

Um erro desse faz com que o programa pare imediatamente!

Um printf() normalmente é escrito no bu�er e não aparece na

saída padrão imediatamente.

Um Seg Fault pode ocorrer depois de um printf() e, como ele

ainda estava no bu�er, não ser direcionado para a saída

padrão.

Para testar e debugar seu programa utilize a saída de erro

padrão, ela não vai para o bu�er, é escrita imediatamente.

Aula 16. Ponteiros II

Segmentation Fault

Normalmente ocorrem quando há a tentativa de acessar uma região

de memória que o programa não tem acesso.

int main() {

int a = 10;

int *p;

p = &a;

p = NULL;

printf("Erro.");

*p = 20;

return 0;

}

Segmentation Fault.

int main() {

int a = 10;

int *p;

p = &a;

p = NULL;

fprintf(stderr, "Erro.");

*p = 20;

return 0;

}

Erro.

Segmentation Fault.

Aula 16. Ponteiros II

Parênteses

Ponteiros são inteiros, portanto, é permitido fazer contas aritmética

com eles.

int main() {

int n = 10;

int *p;

p = &n;

return 0;

}

0x003A4581: 0x0000000A

p

n

0x003A4585: 0x003A4581

p

p

0x003A4589: 0xC0FE5409

p⇒ p

0x003A458D: 0x45413200

p⇒ q

0x003A4591: 0x4B432BC8

p⇒ n

0x003A4595: 0x19374998

p⇒ n

Aula 16. Ponteiros II

Parênteses

Ponteiros são inteiros, portanto, é permitido fazer contas aritmética

com eles.

int main() {

int n = 10;

int *p;

p = &n;

(*p)++;

return 0;

}

0x003A4581: 0x0000000B

p

n

0x003A4585: 0x003A4581

p

p

0x003A4589: 0xC0FE5409

p⇒ p

0x003A458D: 0x45413200

p⇒ q

0x003A4591: 0x4B432BC8

p⇒ n

0x003A4595: 0x19374998

p⇒ n

Aula 16. Ponteiros II

Parênteses

Ponteiros são inteiros, portanto, é permitido fazer contas aritmética

com eles.

int main() {

int n = 10;

int *p;

p = &n;

*p++;

return 0;

}

0x003A4581: 0x0000000A

p

n

0x003A4585: 0x003A4585

p

p

0x003A4589: 0xC0FE5409

p⇒ p

0x003A458D: 0x45413200

p⇒ q

0x003A4591: 0x4B432BC8

p⇒ n

0x003A4595: 0x19374998

p⇒ n

Aula 16. Ponteiros II

Parênteses

Ponteiros são inteiros, portanto, é permitido fazer contas aritmética

com eles.

As operações aritméticas com ponteiros são feitas na unidade

do tamanho do tipo guardado nele.

Aula 16. Ponteiros II

Exemplo

int main() {

char c = `a';

char b = `e';

char **p, *q;

p = &q;

q = &c;

p++;

q++;

printf("%c\n", *q);

printf("%c\n", **p);

return 0;

}

0x003A4581: 0xB9

p c

0x003A4582: 0xAC

p b

0x003A4583: 0xC0FE5409

p p

0x003A4587: 0x45413200

p q

0x003A458B: 0x4B432BC8

p⇒

eSegmentation Fault.

Aula 16. Ponteiros II

Exemplo

int main() {

char c = `A';

char b = `E';

char **p, *q;

p = &q;

q = &c;

p++;

q++;

printf("%c\n", *q);

printf("%c\n", **p);

return 0;

}

0x003A4581: 0x41

p

c

0x003A4582: 0xAC

p b

0x003A4583: 0xC0FE5409

p p

0x003A4587: 0x45413200

p q

0x003A458B: 0x4B432BC8

p⇒

ESegmentation Fault.

Aula 16. Ponteiros II

Exemplo

int main() {

char c = `A';

char b = `E';

char **p, *q;

p = &q;

q = &c;

p++;

q++;

printf("%c\n", *q);

printf("%c\n", **p);

return 0;

}

0x003A4581: 0x41

p

c

0x003A4582: 0x45

p

b

0x003A4583: 0xC0FE5409

p p

0x003A4587: 0x45413200

p q

0x003A458B: 0x4B432BC8

p⇒

ESegmentation Fault.

Aula 16. Ponteiros II

Exemplo

int main() {

char c = `A';

char b = `E';

char **p, *q;

p = &q;

q = &c;

p++;

q++;

printf("%c\n", *q);

printf("%c\n", **p);

return 0;

}

0x003A4581: 0x41

p

c

0x003A4582: 0x45

p

b

0x003A4583: 0xC0FE5409

p

p

0x003A4587: 0x45413200

p

q

0x003A458B: 0x4B432BC8

p⇒

ESegmentation Fault.

Aula 16. Ponteiros II

Exemplo

int main() {

char c = `A';

char b = `E';

char **p, *q;

p = &q;

q = &c;

p++;

q++;

printf("%c\n", *q);

printf("%c\n", **p);

return 0;

}

0x003A4581: 0x41

p

c

0x003A4582: 0x45

p

b

0x003A4583: 0x003A4587

p

p

0x003A4587: 0x45413200

p

q

0x003A458B: 0x4B432BC8

p⇒

ESegmentation Fault.

Aula 16. Ponteiros II

Exemplo

int main() {

char c = `A';

char b = `E';

char **p, *q;

p = &q;

q = &c;

p++;

q++;

printf("%c\n", *q);

printf("%c\n", **p);

return 0;

}

0x003A4581: 0x41

p

c

0x003A4582: 0x45

p

b

0x003A4583: 0x003A4587

p

p

0x003A4587: 0x003A4581

p

q

0x003A458B: 0x4B432BC8

p⇒

ESegmentation Fault.

Aula 16. Ponteiros II

Exemplo

int main() {

char c = `A';

char b = `E';

char **p, *q;

p = &q;

q = &c;

p++;

q++;

printf("%c\n", *q);

printf("%c\n", **p);

return 0;

}

0x003A4581: 0x41

p

c

0x003A4582: 0x45

p

b

0x003A4583: 0x003A458B

p

p

0x003A4587: 0x003A4581

p

q

0x003A458B: 0x4B432BC8

p⇒

ESegmentation Fault.

Aula 16. Ponteiros II

Exemplo

int main() {

char c = `A';

char b = `E';

char **p, *q;

p = &q;

q = &c;

p++;

q++;

printf("%c\n", *q);

printf("%c\n", **p);

return 0;

}

0x003A4581: 0x41

p

c

0x003A4582: 0x45

p

b

0x003A4583: 0x003A458B

p

p

0x003A4587: 0x003A4582

p

q

0x003A458B: 0x4B432BC8

p⇒

ESegmentation Fault.

Aula 16. Ponteiros II

Exemplo

int main() {

char c = `A';

char b = `E';

char **p, *q;

p = &q;

q = &c;

p++;

q++;

printf("%c\n", *q);

printf("%c\n", **p);

return 0;

}

0x003A4581: 0x41

p

c

0x003A4582: 0x45

p

b

0x003A4583: 0x003A458B

p

p

0x003A4587: 0x003A4582

p

q

0x003A458B: 0x4B432BC8

p⇒

E

Segmentation Fault.

Aula 16. Ponteiros II

Exemplo

int main() {

char c = `A';

char b = `E';

char **p, *q;

p = &q;

q = &c;

p++;

q++;

printf("%c\n", *q);

printf("%c\n", **p);

return 0;

}

0x003A4581: 0x41

p

c

0x003A4582: 0x45

p

b

0x003A4583: 0x003A458B

p

p

0x003A4587: 0x003A4582

p

q

0x003A458B: 0x4B432BC8

p⇒

ESegmentation Fault.

Aula 16. Ponteiros II

Exemplo

int main() {

char c = `A';

char b = `E';

char **p, *q;

p = &q;

q = &c;

p++;

q++;

printf("%c\n", *q);

printf("%c\n", **p);

return 0;

}

0x003A4581: 0x41

p

0x003A4582: 0x45

p

0x003A4583: 0x003A458B

p

0x003A4587: 0x003A4582

p

0x003A458B: 0x4B432BC8

p⇒

ESegmentation Fault.

Aula 16. Ponteiros II

Alocação de Memória

int main() {

char* str1, str2, str3;

str1 = "Hello World";

str2 = "Hello";

scanf("%s", str3);

return 0;

}

0x003A4581: 0x003A4632 str1

0x003A4585: 0x003A4940 str2

0x003A4589: 0x254AC570 str3

0x003A4632: "Hello World"

p

0x003A4940: "Hello"

p

0x003A5021: ???

p

Segmentation Fault.

Aula 16. Ponteiros II

Alocação de Memória

int main() {

char* str1, str2, str3;

str1 = "Hello World";

str2 = "Hello";

scanf("%s", str3);

return 0;

}

0x003A4581: 0x003A4632 str1

0x003A4585: 0x003A4940 str2

0x003A4589: 0x254AC570 str3

0x003A4632: "Hello World"

p

0x003A4940: "Hello"

p

0x003A5021: ???

p

Segmentation Fault.

Aula 16. Ponteiros II

Alocação de Memória

int main() {

char* str1, str2, str3;

str1 = "Hello World";

str2 = "Hello";

str3 = (char*) malloc(3);

scanf("%s", str3);

return 0;

}

0x003A4581: 0x003A4632 str1

0x003A4585: 0x003A4940 str2

0x003A4589: 0x003A5021 str3

0x003A4632: "Hello World"

p

0x003A4940: "Hello"

p

0x003A5021: "Ola"

p

Segmentation Fault.

Aula 16. Ponteiros II

Alocação de Memória

int main() {

char* str1, str2, str3;

str1 = "Hello World";

str2 = "Hello";

str3 = (char*) malloc(3);

scanf("%s", str3);

free(str3);

return 0;

}

0x003A4581: 0x003A4632 str1

0x003A4585: 0x003A4940 str2

0x003A4589: 0x003A5021 str3

0x003A4632: "Hello World"

p

0x003A4940: "Hello"

p

0x003A5021: "Ola"

p

Segmentation Fault.

Aula 16. Ponteiros II

Alocação de Memória

malloc(): aloca uma região de memória. Ele retorna um endereço

para aquela região e tem como argumento o tamanho da região a

ser alocada em bytes.

variavel = (tipo) malloc(tamanho);

Aula 16. Ponteiros II

Alocação de Memória

free(): desaloca uma região de memória, liberando espaço na

memória. Precisa somente do endereço da posição de memória.

free(variavel);

Aula 16. Ponteiros II

Exercício

Faça um programa que:

leia um valor n

aloque na memória n inteiros

desaloque a memória

Aula 16. Ponteiros II

Recommended