Anexo 2 - Departamento de Ciencias e Ingeniería de la Computación

Anuncio
Organización de Computadoras
Departamento de Ciencias e Ingeniería de la Computación
Universidad Nacional del Sur
Segundo Cuatrimestre de 2016
Práctico de Programación - Anexo 2
Programación en Lenguaje C
Punteros y pasaje de parámetros por referencia
Ejercicios
1. Considerar los siguientes planteos en el contexto del lenguaje C:
a) ¿Cómo se definen las variables de tipo puntero?
b) ¿Qué estructuras de datos pueden ser apuntadas por una variable de tipo puntero?
c) ¿Es posible declarar una variable de tipo puntero sin especificar a qué estructura de datos
apuntará?
d) ¿La constante NULL, de qué tipo es?
e) ¿Qué diferencia una estructura de datos estática de una dinámica? Encontrar al menos dos
ejemplos de cada categoría.
f ) ¿Una variable de tipo puntero en sí misma, constituye una estructura de datos estática o
dinámica?
g) ¿Cuál es la utilidad de las funciones de librería malloc() y free()?
h) ¿Cómo hace el compilador para saber cuanta memoria debe reservar en el HEAP ante cada
invocación a la función malloc()?
2. Teniendo en cuenta los siguientes fragmentos de código en C, realice un diagrama de ejecución
paso a paso que le permita responder al momento de llegar a cada checkpoint cuál es el valor de
cada variable.
a) void main(){
int* x;
int y;
x = (int*) malloc(sizeof(int));
*x = 3;
y = *x;
//checkpoint 1
y++;
//checkpoint 2
*x ++
//checkpoint 3
free(x);
}
b) void main(){
int* x;
int y;
x = &y;
*x = 3;
//checkpoint 1
1
y++;
//checkpoint 2
*x ++
}
3. Teniendo en cuenta los siguientes fragmentos de código en C, realice un diagrama de ejecución
paso a paso que le permita responder al momento de llegar a cada checkpoint
¿Para cuáles de las variables definidas es modificable su valor?
¿Qué valor tiene cada una?
a)
void main(){
double myVar = 123.4;
f(myVar);
//checkpoint3!
}
void f(double formal){
//checkpoint1
formal = formal + 56.75;
//checkpoint2!
}
void main(){
double myVar = 123.4;
f(&myVar);
//checkpoint3!
}
void f(double* formal){
//checkpoint1
*formal = *formal + 56.75;
//checkpoint2!
}
void main(){
double myVar = 123.4;
double* p;
p = &myVar;
f(*p);
//checkpoint3!
}
void f(double formal){
//checkpoint1
formal = formal + 56.75;
//checkpoint2!
}
void main(){
double myVar = 123.4;
double* p;
p = &myVar;
f(p);
//checkpoint3!
}
void f(double* formal){
//checkpoint1
*formal = *formal + 56.75;
//checkpoint2!
}
void main(){
double myVar = 123.4;
double* p;
p = &myVar;
f(&p);
//checkpoint4!
}
void f(double** formal){
//checkpoint1
**formal = **formal + 56.75;
*formal = NULL;
//checkpoint2!
formal = NULL;
//checkpoint3!
}
b)
c)
d)
e)
4. Supongamos un programa que haciendo uso de la función tri triplica el valor de un entero. De
las soluciones planteadas a continuación todas compilan, sin embargo, no todas las soluciones son
correctas (aunque algunas funcionen). Analice cada una de ella e identifique cuál es el problema.
2
a)
void main(){
int a = 34;
int a3;
int* p;
p = tri(a);
a3 = *p;
}
int* tri(int x){
int res;
res = 3 * x;
return &res;
}
void main(){
int a = 34;
int a3;
int* p;
p = tri(a);
a3 = *p;
}
int* tri(int x){
int* res;
*res = 3 * x;
return res;
}
void main(){
int a = 34;
int a3;
int* p;
p = tri(a);
a3 = *p;
free(p);
}
int* tri(int x){
int* res;
res = (int*) malloc(sizeof(int));
*res = 3 * x;
return res;
}
void main(){
int a = 34;
int a3;
a3 = tri(a);
}
int tri(int x){
int res = 3 * x;
return res;
}
void main(){
int a = 34;
int a3;
a3 = tri(a);
}
int tri(int x){
int* res;
res = (int*) malloc(sizeof(int));
*res = 3 * x;
return *res;
}
void main(){
int a = 34;
tri(&a);
}
void tri(int* x){
int res;
res = *x * 3;
*x = res;
}
void main(){
int* a;
*a = 34;
tri(a);
}
void tri(int* x){
int res;
res = *x * 3;
*x = res;
}
b)
c)
d)
e)
f)
g)
3
h)
void main(){
int* a;
a = (int*)malloc(sizeof(int));
*a = 34;
tri(a);
}
void tri(int* x){
int res;
res = *x * 3;
*x = res;
}
5. Recursión y pasaje de parámetros por referencia
Dado un número entero positivo N = dn . . . d2 d1 d0 (di 6= 0∀i) ingresado por teclado se desea
P
saber para cuántos dígitos de N se cumple que di sea divisor de ik=0 dk . Por ejemplo, el número
N = 46712 tiene 3 dígitos que cumplen la propiedad:
2
1
7
6
4
es divisor de 2
es divisor de 2 + 1 = 3
no es divisor de 2 + 1 + 7 = 10
no es divisor de 2 + 1 + 7 + 6 = 16
es divisor de 2 + 1 + 7 + 6 + 4 = 20
a) Implementar en C una función int leerDigito() que lea un caracter y retorne un entero
entre 1 y 9 si lee un caracter del 1 al 9. Cualquier otro caso devuelve -1.
b) Implementar en C una única función recursiva propiedad que invocando la función del
inciso (5a) lea uno a uno los dígitos del número y resuelva el problema enunciado.
Se puede asumir que el número termina con el primer caracter que no sea un dígito del 1
al 9.
c) Completar en la siguiente función cáscara el código necesario para llamar a la función del
inciso anterior.
int cantidad() {
...
return propiedad(...)
}
Referencias
[1] C Programming. https://en.wikibooks.org/wiki/C_Programming
Pdf: https://upload.wikimedia.org/wikipedia/commons/0/07/C_Programming.pdf.
[2] Brian Kernighan and Dennis Ritchie. The C Programming Language. Prentice-Hall, second edition,
1988.
4
Descargar