Programação de Computadores II 2019.1
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: 0x003A4589: 0x003A4585 0x00000000 0x19374998 p n O valor de n eh: 0x00000000 O endereço de n é: 0x003A4585 O valor de *n é: ERROR O valor de p é: 0x003A4585 O endereço de p é: 0x003A4581 O valor de *p é: 0x00000000
Endereço e Ponteiro Ponteiros e endereços são sempre utilizados juntos.
Registro typedef struct aluno { int matricula; float nota; char *nome; Aluno; Aluno a; Aluno *p; p = &a; 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 (12 bytes: um int, um float e um endereço).
Registro typedef struct aluno { int matricula; float nota; char *nome; Aluno; Aluno a; Aluno *p; p = &a;
Registro typedef struct aluno { int matricula; float nota; char *nome; Aluno; Aluno a; Aluno *p; p = &a; A variável nome terá o mesmo tamanho da variável p, o tamanho de um endereço de memória.
Registro typedef struct aluno { int matricula; float nota; char *nome; Aluno; Aluno a; Aluno *p; p = &a; (*p).nota = 10; p->nota = 10; a.nota = 10; (*p).nome é equivalente a p->nome
Ponteiro para Ponteiro 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); 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
Segmentation Fault Normalmente ocorrem quando há tentativa de acessar uma região de memória que o programa não tem acesso. int a = 10, b = 20; int *p, *q; p = &a; *q = 10; q = &b; *p = 15; p = &a;
Segmentation Fault Normalmente ocorrem quando há tentativa de acessar uma região de memória que o programa não tem acesso. int a = 10, b = 20; int *p, *q; p = &a; q = NULL; *q = 10; q = &b; *p = 15; p = &a;
Segmentation Fault Normalmente ocorrem quando há tentativa de acessar uma região de memória que o programa não tem acesso. int a = 10, b = 20; int *p, *q; p = &a; q = &b; *q = 10; *p = 15; p = &a;
Segmentation Fault Normalmente ocorrem quando há tentativa de acessar uma região de memória que o programa não tem acesso. char* str1, str2, str3; str1 = "Hello World"; str2 = "Hello"; printf("%c", str1[0]); printf("%c", str2[0]); printf("%c", str3[0]);
Segmentation Fault Normalmente ocorrem quando há tentativa de acessar uma região de memória que o programa não tem acesso. char* str1, str2, str3; str1 = "Hello World"; str2 = "Hello"; printf("%c", str1[0]); printf("%c", str2[0]); printf("%c", str3[0]);
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 buffer 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 buffer, não ser direcionado para a saída padrão. Para testar e debugar seu programa utilize a saída de erro, ela não vai para o buffer, é escrita imediatamente.
Segmentation Fault Normalmente ocorrem quando há tentativa de acessar uma região de memória que o programa não tem acesso. int a = 10; int *p; p = &a; p = NULL; printf("erro."); *p = 20; Segmentation Fault. int a = 10; int *p; p = &a; p = NULL; fprintf(stderr, "Erro."); *p = 20; Erro. Segmentation Fault.
Parênteses Ponteiros são inteiros, portanto, é permitido fazer contas aritmética com eles. int n = 10; int *p; p = &n; 0x003A4581: 0x003A4585: 0x003A4589: 0x003A458D: 0x003A4591: 0x003A4595: 0x0000000A 0x003A4581 0xC0FE5409 0x45413200 0x4B432BC8 0x19374998 n p
Parênteses Ponteiros são inteiros, portanto, é permitido fazer contas aritmética com eles. int n = 10; int *p; p = &n; (*p)++; 0x003A4581: 0x003A4585: 0x003A4589: 0x003A458D: 0x003A4591: 0x003A4595: 0x0000000B 0x003A4581 0xC0FE5409 0x45413200 0x4B432BC8 0x19374998 n p
Parênteses Ponteiros são inteiros, portanto, é permitido fazer contas aritmética com eles. int n = 10; int *p; p = &n; *p++; 0x003A4581: 0x003A4585: 0x003A4589: 0x003A458D: 0x003A4591: 0x003A4595: 0x0000000A 0x003A4585 0xC0FE5409 0x45413200 0x4B432BC8 0x19374998 n p
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.
Exemplo char c = a ; char b = e ; char **p, *q; p = &q; q = &c; p++; q++; printf("%c\n", *q); printf("%c\n", **p); 0x003A4581: 0x003A4582: 0x003A4583: 0x003A4587: 0x003A458B: 0xB9 0xAC 0xC0FE5409 0x45413200 0x4B432BC8
Exemplo char c = A ; char b = E ; char **p, *q; p = &q; q = &c; p++; q++; printf("%c\n", *q); printf("%c\n", **p); 0x003A4581: 0x003A4582: 0x003A4583: 0x003A4587: 0x003A458B: 0x41 0xAC 0xC0FE5409 0x45413200 0x4B432BC8 c
Exemplo char c = A ; char b = E ; char **p, *q; p = &q; q = &c; p++; q++; printf("%c\n", *q); printf("%c\n", **p); 0x003A4581: 0x003A4582: 0x003A4583: 0x003A4587: 0x003A458B: 0x41 0x45 0xC0FE5409 0x45413200 0x4B432BC8 c b
Exemplo char c = A ; char b = E ; char **p, *q; p = &q; q = &c; p++; q++; printf("%c\n", *q); printf("%c\n", **p); 0x003A4581: 0x003A4582: 0x003A4583: 0x003A4587: 0x003A458B: 0x41 0x45 0xC0FE5409 0x45413200 0x4B432BC8 c b p q
Exemplo char c = A ; char b = E ; char **p, *q; p = &q; q = &c; p++; q++; printf("%c\n", *q); printf("%c\n", **p); 0x003A4581: 0x003A4582: 0x003A4583: 0x003A4587: 0x003A458B: 0x41 0x45 0x003A4587 0x45413200 0x4B432BC8 c b p q
Exemplo char c = A ; char b = E ; char **p, *q; p = &q; q = &c; p++; q++; printf("%c\n", *q); printf("%c\n", **p); 0x003A4581: 0x003A4582: 0x003A4583: 0x003A4587: 0x003A458B: 0x41 0x45 0x003A4587 0x003A4581 0x4B432BC8 c b p q
Exemplo char c = A ; char b = E ; char **p, *q; p = &q; q = &c; p++; q++; printf("%c\n", *q); printf("%c\n", **p); 0x003A4581: 0x003A4582: 0x003A4583: 0x003A4587: 0x003A458B: 0x41 0x45 0x003A4588 0x003A4581 0x4B432BC8 c b p q
Exemplo char c = A ; char b = E ; char **p, *q; p = &q; q = &c; p++; q++; printf("%c\n", *q); printf("%c\n", **p); 0x003A4581: 0x003A4582: 0x003A4583: 0x003A4587: 0x003A458B: 0x41 0x45 0x003A458B 0x003A4582 0x4B432BC8 c b p q
Exemplo char c = A ; char b = E ; char **p, *q; p = &q; q = &c; p++; q++; printf("%c\n", *q); printf("%c\n", **p); 0x003A4581: 0x003A4582: 0x003A4583: 0x003A4587: 0x003A458B: E 0x41 0x45 0x003A458B 0x003A4582 0x4B432BC8 c b p q
Exemplo char c = A ; char b = E ; char **p, *q; p = &q; q = &c; p++; q++; printf("%c\n", *q); printf("%c\n", **p); 0x003A4581: 0x003A4582: 0x003A4583: 0x003A4587: 0x003A458B: E Segmentation Fault. 0x41 0x45 0x003A458B 0x003A4582 0x4B432BC8 c b p q
Exemplo char c = A ; char b = E ; char **p, *q; p = &q; q = &c; p++; q++; printf("%c\n", *q); printf("%c\n", **p); 0x003A4581: 0x003A4582: 0x003A4583: 0x003A4587: 0x003A458B: E Segmentation Fault. 0x41 0x45 0x003A458B 0x003A4582 0x4B432BC8
Alocação de Memória char* str1, str2, str3; str1 = "Hello World"; str2 = "Hello"; scanf("%s", str3); 0x003A4581: 0x003A4632 str1 0x003A4585: 0x003A4940 str2 0x003A4589: 0x254AC570 str3 0x003A4632: "Hello World" 0x003A4940: "Hello" 0x003A5021:???
Alocação de Memória char* str1, str2, str3; str1 = "Hello World"; str2 = "Hello"; scanf("%s", str3); 0x003A4581: 0x003A4632 str1 0x003A4585: 0x003A4940 str2 0x003A4589: 0x254AC570 str3 0x003A4632: "Hello World" 0x003A4940: "Hello" 0x003A5021:??? Segmentation Fault.
Alocação de Memória char* str1, str2, str3; str1 = "Hello World"; str2 = "Hello"; str3 = (char*) malloc(4); scanf("%s", str3); 0x003A4581: 0x003A4585: 0x003A4589: 0x003A4632: 0x003A4940: 0x003A5021: 0x003A4632 str1 0x003A4940 str2 0x003A5021 str3 "Hello World" "Hello" "Ola"
Alocação de Memória char* str1, str2, str3; str1 = "Hello World"; str2 = "Hello"; str3 = (char*) malloc(4); scanf("%s", str3); free(str3); 0x003A4581: 0x003A4585: 0x003A4589: 0x003A4632: 0x003A4940: 0x003A5021: 0x003A4632 str1 0x003A4940 str2 0x003A5021 str3 "Hello World" "Hello" "Ola"
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. ponteiro = (tipo) malloc(tamanho); int *p; p = (int *) malloc(sizeof(int))
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(ponteiro); int *p; p = (int *) malloc(sizeof(int)) free(p)
Exercício Faça um programa que: leia um valor n aloque na memória um ponteiro para n inteiros desaloque a memória
Exercício: Solução #include <stdio.h> #include <stdlib.h> // leia um valor n int n; scanf("%d", &n); // aloque na memória um ponteiro para n inteiros int* v = (int*) malloc(n*sizeof(int)); // desaloque a free(v);