Punteros y arreglos

Transcripción

Punteros y arreglos
Programación científica
Punteros y arreglos
Dra. Elisa Schaeffer
[email protected]
PISIS / FIME / UANL
Punteros y arreglos– p. 1
Arreglo
Un arreglo es un conjunto de una cantidad fija de
variables del mismo tipo que se maneja por el mismo
nombre a través de ı́ndices:
int elementos[5]; /* ANSI-C */
int i = 3;
int[] elementos = new int[i]; /* Java */
elementos[i] = 4;
Los índices comienzan de cero y terminan en n − 1
donde n es el número total de elementos.
Punteros y arreglos– p. 2
Cayendo afuera: ANSI-C
#include <stdio.c>
int main(int argc, char** args) {
int data[5];
data[5] = 3;
printf("Done.\n");
return 1;
}
Punteros y arreglos– p. 3
Reacciones variadas
@ubuntu$ gcc errores.c
@ubuntu$ ./a.out
Done.
Bus error (core dumped)
@ubuntu$
@yalma$ gcc errores.c
@yalma$ ./a.out
Done.
@yalma$
Punteros y arreglos– p. 4
Cayendo afuera en Java
public class Errores {
public static void main(String[] args) {
int[] data = new int[5];
data[5] = 3;
System.out.println("Done.");
return;
}
}
Punteros y arreglos– p. 5
Reacción consistente
$ java Errores
Exception in thread "main"
java.lang.ArrayIndexOutOfBoundsException: 5
at Errores.main(Errores.java:4)
$
Punteros y arreglos– p. 6
Arreglos multidimensionales
int multi[3][4];
int a, b;
for (a = 0; a < 3; a++) {
for (b = 0; b < 4; b++) {
multi[a][b] = rand() % 7;
}
}
for (a = 0; a < 3; a++) {
for (b = 0; b < 4; b++) {
printf(" %d", multi[a][b]);
}
printf("\n");
}
Punteros y arreglos– p. 7
Puntero
En C, para crear arreglos sacando la capacidad de una
variable, se necesita punteros.
Un puntero es una variable que contiene la
otra variable en la memoria.
dirección a
Los punteros son unas maravillas sin los cuales uno lo
logra nada útil en ANSI-C en el largo plazo.
Punteros y arreglos– p. 8
Definición de punteros
#include <stdio.h>
int main(int argc, char** args) {
char* puntero_a_char;
int* puntero_a_int;
char a = ’a’;
int b = 7;
puntero_a_char = &a;
puntero_a_int = &b;
printf("%c %d\n",
*puntero_a_char, *puntero_a_int);
return 1;
}
Punteros y arreglos– p. 9
Notación
*t
&a
*b
= puntero a una variable de tipo t
= dirección de la variable a
= valor apuntado por el puntero b
El compilador queja siempre y cuando uno usa mal esta
notación.
Punteros y arreglos– p. 10
Tamaño de tipo
Al reservar memoria, vamos a recibir un puntero a la
región reservada.
Al reservar, vamos a necesitar saber cuánto espacio
reservar. La función sizeof(tipo) devuelve un entero
que indica cuántos bytes necesita una variable del tipo
definido.
La salida de sizeof() es de tipo size_t que es
simplemente un entero constante sin signo. El espacio
necesario para k variables se calcula por multiplicar: por
ejemplo k*sizeof(int), donde k puede ser constante o
variable.
Punteros y arreglos– p. 11
sizeof()
#include <stdio.h>
int main(int argc, char** args) {
size_t charsize = sizeof(char);
size_t intsize = sizeof(int);
size_t longsize = sizeof(long);
size_t floatsize = sizeof(float);
size_t doublesize = sizeof(double);
printf("char %d, int %d, long %d, float %d, double %d\n",
charsize, intsize, longsize, floatsize, doublesize);
return 1;
}
Salida: char 1, int 4, long 4, float 4, double 8
Punteros y arreglos– p. 12
Reservación de memoria
void* malloc(size_t n)
= reservar n bytes de memoria
void* cealloc(size_t n)
= reservar e inicializar a cero
void* realloc(void* p, size_t n)
= aumentar la región
free(void* p)
= liberar el espacio apuntado por el puntero
Punteros y arreglos– p. 13
Conversión de void
Las salidas son tipo void .
Para asignar la salida de malloc() a un int ∗, por
ejemplo, hay que hacer conversión explícita (inglés: type
casting):
int* d = (int*)malloc(7*sizeof(int));
m/c/realloc da la salida NULL si la operación no es
éxitosa. Es importante verificar esto en cada programa.
Son de la librería stdlib.h .
Punteros y arreglos– p. 14
Punteros a punteros
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** args) {
int i, j, h, k = 4;
int*** tresd = (int***)malloc(sizeof(int**)*k);
for (i = 0; i < k; i++) {
tresd[i] = (int**)malloc(sizeof(int*)*(k-1));
for (j = 0; j < k - 1; j++) {
tresd[i][j] = (int*)malloc(sizeof(int)*(k-2));
for (h = 0; h < k - 2; h++) {
tresd[i][j][h] = rand() % 10;
}
}
}
return 1;
}
Punteros y arreglos– p. 15
¿Resultado?
Lo que imprime el programa anterior:
1
6
8
3
2
0
7
7
7
6
9
5
0
2
2
9
9
6
0
2
3
1
2
2
Nota: falta verificar el resultado de malloc()
Punteros y arreglos– p. 16
string.h
char* strcpy(char*, char*)
copiar el segundo al primero
char* strcat(char*, char*)
juntar dos en uno
int strcmp(char*, char*)
La librería string.h
permite
realizar
varias operaciones
con arreglos de char
o punteros a char .
La lista muestra una
pequeñ parte.
comparar (antes, igual, después)
char* strchr(char*, int)
la primera ocurrencia de un símbolo
char* strstr(char*, char*)
primera ocurrencia de otra cadena
size_t strlen(char*)
largo (número de símbolos “ocupados”)
Punteros y arreglos– p. 17
Puntero a función
Funciones que dan el mismo tipo de salida y toman los
mismos tipos de parámetros se puede manejar a
través de un puntero de ese “prototipo”:
double multiply(int a, double b) {
printf("%.4f\n", b*a);
return b*a;
}
typedef double (*funpoint)(int, double);
Punteros y arreglos– p. 18
Uso de punteros a funciones
Tres maneras de llamar la misma función:
funpoint fp = &multiply;
multiply(3, 1.2);
(*fp)(3, 1.2);
fp(3, 1.2);
Punteros y arreglos– p. 19
Función como parámetro
#include <stdio.h> // printf()
#include <stdlib.h> // RAND\_MAX
... // lo de la dispositiva anterior
void task(funpoint f) {
int first = rand() % 7;
double second = (rand()*1.0)/RAND\_MAX;
f(first, second);
return;
}
int main(int argc, char** args) {
funpoint fp = &multiply;
task(fp);
return 1;
}
Punteros y arreglos– p. 20

Documentos relacionados