Coprimos
Dos números enteros se dicen coprimos si y
sólo si el M.C.D. entre ellos es 1. Por ejemplo:
m.c.d(17,91) = 1 luego 17 y 91 son coprimos
- Prog083
/* Prog083.cpp */
/* Determinar los dos 'int' más grandes
que
sean 'coprimos' */
#include <stdio.h>
#include <values.h>
int MCD(int x,int y);
void main()
{
int max,num1,num2;
int i=1;
max=MAXINT;
while (MCD(max,MAXINT-i) != 1) i++;
num1=MAXINT;
num2=MAXINT-i;
printf("n Los 2 números mayores coprimos
tipo 'int' son %d y %d",num1,num2);
printf("nn C O M P R O B A C I O
N:");
printf("nMáximo INT=
%d",MAXINT);
printf("nnMCD de %d y %d es
%d",num1,num2,MCD(num1,num2));
}
int MCD(int x,int y)
{
int aux,resto;
if (x<y)
{
aux=x;
x=y;
y=aux;
}
if ((x % y)==0) resto=y;
while ((x % y) != 0)
{
resto=x-y*(x/y);
x=y;
y=resto;
}
return resto;
}
Recuerda:
- Escribe el programa
anterior utilizando tu compilador. - Grábalo con el nombre Prog083.cpp en
TuCarpeta. - Ejecútalo un par o tres de veces
- Prog084
/* Prog084.cpp */
/* Matriz tal
que Aij=1 si i,j son coprimos
Aij=0 si i,j no son coprimos */
#include <stdio.h>
int MCD(int x,int y);
void main()
{
int n; int i,j;
int matr[20][20];
printf("nOrden de la matriz: ");
scanf("%d",&n);
printf("nn");
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(MCD(i+1,j+1)==1)
matr[i][j]=1;
else
matr[i][j]=0;
printf("%d ",matr[i][j]);
};
printf("n");
}
}
int MCD(int x,int y)
{
int aux,resto;
if (x<y)
{
aux=x;
x=y;
y=aux;
}
if ((x % y)==0) resto=y;
while ((x % y) != 0)
{
resto=x-y*(x/y);
x=y;
y=resto;
}
return resto;
}
AUTOEVALUACIÓN 3
- Haz un programa que calcule el producto
vectorial de 2 vectores del
espacio. Graba el programa con el nombre
EVAL3A.Graba el programa con el nombre
EVAL3B.- Haz un programa que calcule el módulo de un
vector en el espacio, utilizando una función con retorno de parámetro
(guíate por el PROG057)Graba el programa con el nombre
EVAL3C. - Haz un programa que calcule el área de un
triángulo en el espacio, dadas las coordenadas de los 3
vértices (utiliza la función del programa
EVAL3B) - Haz un programa que funcione de la siguiente
forma:
- El programa nos pide 10 valores
(serie estadística). - El programa calcula la media aritmética
(función con retorno de parámetro). - El programa calcula las desviaciones respecto a la
media. - El programa calcula la desviación media
(llamada a la misma función de antes). - El programa calcula la desviación
típica (llamada a la misma función de
antes)
Graba el programa con el nombre EVAL3D
- Escribe el siguiente programa:
/* eval3e */
#include <stdio.h>
#include <math.h>
float modul(float v[3]);
void main()
{
int i;
float a[3],b[3],c[3];
float v1[3],v2[3];
float provect[3];
float modu,area;
printf("n Introduce las coordenadas del punto A:
n");
for(i=0;i<2;i++)
scanf("%f",&a[i]);
a[2]=0;
printf("n Introduce las coordenadas del punto B:
n");
for(i=0;i<2;i++)
scanf("%f",&b[i]);
b[2]=0;
printf("n Introduce las coordenadas del punto C:
n");
for(i=0;i<2;i++)
scanf("%f",&c[i]);
c[2]=0;
printf("nn Punto A =
(%f,%f,%f)",a[0],a[1],a[2]);
printf("nn Punto B =
(%f,%f,%f)",b[0],b[1],b[2]);
printf("nn Punto C =
(%f,%f,%f)",c[0],c[1],c[2]);
for(i=0;i<3;i++)
{
v1[i]=b[i]-a[i];
v2[i]=c[i]-a[i];
}
printf("nn Vector AB =
(%f,%f,%f)",v1[0],v1[1],v1[2]);
printf("nn Vector AC =
(%f,%f,%f)",v2[0],v2[1],v2[2]);
provect[0]=v1[1]*v2[2]-v2[1]*v1[2];
provect[1]=v2[0]*v1[2]-v1[0]*v2[2];
provect[2]=v1[0]*v2[1]-v2[0]*v1[1];
printf("nn Producto Vectorial AB^AC =
(%f,%f,%f)",provect[0],provect[1],provect[2]);
modu=modul(provect);
printf("nnn Módulo del producto Vectorial =
%f ",modu);
area=0.5*modu;
printf("nn Área del triangulo =
%f",area);
}
float modul(float v[3])
{
float modu;
modu=sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
return modu;
}
- Grábalo con el nombre
EVAL3E - Ejecútalo varias veces.
- Explica qué es lo que hace. Compáralo
con el EVAL3C.
- Haz un programa de nombre EVAL3F que sirva
para elevar al cubo un número, pero utilizando una
función. - Haz un programa de nombre EVAL3G que haga lo
mismo que el anterior pero no a través de una
función sino de una macro. - Haz un programa de nombre EVAL3H que
transforme un número en base 10 a base 4 y 5 - Haz un programa de nombre EVAL3I que haga lo
mismo que el EVAL3A pero utiliza la función
gotoxy para que la salida por pantalla sea más
estética. - Haz un programa de nombre EVAL3J que construya
el triángulo de Tartaglia o de
Pascal.
IV.- Punteros
y Arrays
- Constantes Simbólicas
- Prog085
/* Prog085 */
#include <stdio.h>
#include <math.h>
void sencos(float inicial,float
paso);
void main()
{
float inicial,paso;
printf("n Valor
inicial y incremento ?n");
scanf("%f
%f",&inicial,&paso);
sencos(inicial,paso);
}
void sencos(float inicial,float
paso)
{
int i;
double v[50],s[50],c[50];
for(i=0;i<50;i++)
{
v[i]=(double)(inicial+i*paso);
s[i]=sin(v[i]);
c[i]=cos(v[i]);
}
for(i=0;i<50;i++) printf("n%10lf %10lf
%10lf",v[i],s[i],c[i]);
}
Recuerda:
- Escribe el programa anterior utilizando tu
compilador. - Grábalo con el nombre Prog085.cpp en
TuCarpeta. - Ejecútalo un par o tres de veces
Estudio del PROG085:
Es importante que tengas el PROG058 a la vista,
para poder
compararlo con el PROG085
- En el PROG058 el número de valores de la tabla
de senos y cosenos correspondía a una variable (num), en
nuestro caso (PROG085) el número de valores es fijo:
50. - En el PROG058 las variables
inicial y paso eran double, encambio en el
PROG085 las declaramos float. - El argumento de las funciones sin()
y cos() (funciones que hay en la librería math.h) debe
ser double. Por esta razón en el PROG085 hemos de
transformar el argumento que es float a double. Y esto lo
conseguimos de la siguiente forma:
v[i]=(double)(inicial+i*paso); Es decir, basta escribir
double entre parentesis antes de la expresión que es
float, también entre paréntesis:
(inicial+i*paso) - En el PROG058 las variables v, s, c son simples,
encambio en el PROG085 utilizamos arrays: v[50], s[50] y
c[50]
Nos gustaría modificar el PROG085 de forma que en
lugar de 50 valores, sea otro número, pero que esta
modificación sea fácil de hacer: vamos a utilizar
las llamadas constantes
simbólicas…
Escribe, a partir del PROG085, el siguiente
programa:
– Prog086
/* Prog086.cpp */
#include <stdio.h>
#include <math.h>
#define tam 50
void sencos(float inicial,float
paso);
void main()
{
float inicial,paso;
printf("n Valor inicial y incremento
?n");
scanf("%f
%f",&inicial,&paso);
sencos(inicial,paso);
}
void sencos(float inicial,float
paso)
{
int i;
double v[tam],s[tam],c[tam];
for(i=0;i<tam;i++)
{
v[i]=(double)(inicial+i*paso);
s[i]=sin(v[i]);
c[i]=cos(v[i]);
}
for(i=0;i<tam;i++) printf("n%10lf %10lf
%10lf",v[i],s[i],c[i]);
}
Estudio del PROG086:
- #define tam 50, definimos una constante
simbólica de nombre tam y valor igual a
50. En el resto del programa, donde aparece tam,
el compilador entiende 50. - La utilidad de una
constante simbólica está en que basta cambiar el
número 50, que hay al final de la línea
define, por el número que queramos, para que el
programa funcione exactamente igual pero con un valor de
tam igual al nuevo valor introducido.
Pruébalo.
- La función rand()
- Prog087
/* Prog087.cpp */
#include <stdio.h>
#include <stdlib.h>
#define num 20
void main()
{
int vect[num];
int i;
char nada[1];
printf("n Listado de números aleatorios
entre 0 y 9 n");
for(i=0;i<num;i++)
{
vect[i]=rand() % 10;
printf("n %d",vect[i]);
}
printf("nn Continuo (s/n) ? ");
scanf("%s",&nada);
if (nada[0]=='n') return;
printf("n Listado de números aleatorios
entre 0 y 10 n");
for(i=0;i<num;i++)
{
vect[i]=rand() % 11;
printf("n %d",vect[i]);
}
printf("nn Continuo (s/n) ? ");
scanf("%s",&nada);
if (nada[0]=='n') return;
printf("n Listado de números aleatorios
entre 0 y 99 n");
for(i=0;i<num;i++)
{
vect[i]=rand() % 100;
printf("n %d",vect[i]);
}
printf("nn Continuo (s/n) ? ");
scanf("%s",&nada);
if (nada[0]=='n') return;
printf("n Listado de números aleatorios
entre 1 y 6 n");
for(i=0;i<num;i++)
{
vect[i]=(rand() % 6)+1;
printf("n %d",vect[i]);
}
}
Recuerda:
- Escribe el programa anterior utilizando tu
compilador. - Grábalo con el nombre Prog087.cpp en
TuCarpeta. - Ejecútalo un par o tres de veces
Estudio del PROG087:
- En este programa utilizamos una nueva función:
rand(). Dicha función se encuentra en la biblioteca
stdlib.h, por esta razón necesitamos escribir la
línea: #include <stdlib.h> - Funcionamiento de la función
rand():
rand() % 10: determina un número aleatorio
entre 0 y 9 (incluidos los dos):
rand() % 11: " " " " 0 y 10 "
rand() % 100: : " " " " 0 y 99 "
(rand() % 6)+1: " " " 1 y 6 "
- En realidad la función rand() genera
números pseudoaleatorios, es decir cada vez que
ejecutemos el programa, la sucesión de números
"rand" será la misma. - Si necesitamos "series de rand()" distintas,
basta anteponer una línea de contenido
srand(semilla), función que también
está en stdlib.h, con "semilla" un número
entero. Es decir si escribimos srand(1) la serie de
números "rand" será distinta si escribimos
srand(2). Dicho de otra forma: según el valor de
"semilla" obtendremos una serie de números
pseudoaleatorios u otra.
Vamos a hacer un programa que ordene un listado de 20
números.
- Prog088
/* Prog088.cpp */
#include <stdio.h>
#include <stdlib.h>
void main()
{
int vect[20];
int i,j;
int aux;
char nada[1];
printf("n Listado de números entre 0 y 100
n");
for(i=0;i<20;i++)
{
vect[i]=rand() % 100;
printf("n El número %d es
%d",i,vect[i]);
}
printf("nn Continuo (s/n) ? ");
scanf("%s",&nada);
if (nada[0]=='n') return;
printf("n Vamos a ordenar los
números");
for(i=0;i<20;i++)
{
printf("n Determinando el
número que debe ocupar el lugar %d",i);
for(j=i+1;j<20;j++)
{
printf(".");
if(vect[j]<vect[i])
{
aux=vect[j];
vect[j]=vect[i];
vect[i]=aux;
}
}
}
printf("nn Continuo (s/n) ? ");
scanf("%s",&nada);
if (nada[0]=='n') return;
printf("nn La lista ordenada es:
nn");
for(i=0;i<20;i++) printf("El número %d es
%d n",i,vect[i]);
}
Recuerda:
- Escribe el programa anterior utilizando tu
compilador. - Grábalo con el nombre Prog088.cpp en
TuCarpeta. - Ejecútalo un par o tres de veces
Estudio del PROG088:
- El problema central es: "dadas 2 variables vect[j],
vect[i] cómo intercambiamos sus valores". Es decir, nos
interesa asignar a vect[j] el valor de vect[i] y
viceversa.
Observa la solución:
aux=vect[j];
vect[j]=vect[i];
vect[i]=aux;
siendo aux una variable auxiliar que hace de
puente.
- Está claro que con:
if(vect[j]<vect[i])
{
aux=vect[j];
vect[j]=vect[i];
vect[i]=aux;
}
Conseguimos colocar los números menores
delante. En definitiva, lo que conseguimos es ordenar
los valores
del array vect[20]
- Prog089
/* Prog089.cpp */
/* Programa: Multiplicaciones
El programa nos pide '¿Cuántas
multiplicaciones?' queremos
El programa nos las pregunta
aleatoriamente.
Al final, el programa nos da la nota.
*/
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
void main()
{
int n,a,b,result;
int i;
int bien,mal;
bien=0;mal=0;
printf("n¿Cuántas Multiplicaciones?
");scanf("%d",&n);
for (i=1;i<=n;i++)
{
clrscr();
a=rand() % 10;
b=rand() % 10;
printf("%d x %d =
",a,b);scanf("%d",&result);
if (result==a*b)
{
printf("n MUY
BIEN");
bien=bien+1;
printf("nnPulsa una tecla para continuar
…");
getche();
clrscr();
}
else
{
printf("n NO ES CORRECTO ");
printf("n %d x %d = %d
",a,b,a*b);
mal=mal+1;
printf("nn Pulsa una tecla para continuar
…");
getche();
clrscr();
};
}
clrscr();
printf("n Bien = %d Mal =
%d",bien,mal);
printf("nn NOTA =
%d",int(bien*10/n));
}
- Arrays Multidimensionales
Hasta ahora los arrays que hemos utilizado eran de una
dimensión, vamos a ver ahora un array bidimensional (tabla
de doble entrada).
- Prog090
/* Prog090.cpp */
#include <stdio.h>
#include <stdlib.h>
void main()
{
int matriz[20][5];
int i,j;
int aux;
char nada[1];
printf("Vamos a generar un listado de notas
nn");
for(i=0;i<20;i++)
{
printf("n Fila %3d: ",i);
for(j=1;j<5;j++)
{
matriz[i][j]=rand() % 10;
printf("%d",matriz[i][j]);
printf(" ");
}
}
printf("nn Continuo (s/n) ? ");
scanf("%s",&nada);
if (nada[0]=='n') return;
printf("nn Vamos a calcular la media
nn");
for(i=0;i<20;i++)
{
printf("n La media de la fila %2d
es: ",i);
aux=0;
for(j=1;j<5;j++)
aux=aux+matriz[i][j];
matriz[i][0]=aux/4;
printf("%5d",matriz[i][0]);
}
}
Estudio del PROG090:
- El programa utiliza un array bidimensional
(matriz[20][5]) de 20 filas y 5 columnas, que simula las notas
de 20 alumnos en 4 asignaturas. En la columna 0 del array, el
programa coloca la media de las notas. - Observa la línea:
matriz[i][0]=aux/4;
La división entre números enteros (aux y
4), se trunca automáticamente para que sea otro entero
(matriz[i][0])
- Prog091
/* Prog091.cpp */
#include <stdio.h>
void main()
{
int m1[2][2];
int m2[2][2];
int prod[2][2];
int i,j;
int aux;
/* Introducción de las matrices
*/
printf("n Primera matriz n");
for(i=0;i<2;i++)
{
printf("n Escribe los elementos de
la fila %d:n",i+1);
for(j=0;j<2;j++)
scanf("%d",&m1[i][j]);
}
printf("n Segunda matriz n");
for(i=0;i<2;i++)
{
printf("n Escribe los elementos de
la fila %d:n",i+1);
for(j=0;j<2;j++)
scanf("%d",&m2[i][j]);
}
/* Escritura de
las dos matrices */
printf("nn Tenemos: nn");
for(i=0;i<2;i++)
{
printf(" | ");
for(j=0;j<2;j++)
{
printf("%3d",m1[i][j]);
}
printf(" | | ");
for(j=0;j<2;j++)
{
printf("%3d",m2[i][j]);
}
printf(" | n");
}
/* Cálculo
del producto */
prod[0][0]=m1[0][0]*m2[0][0]+m1[0][1]*m2[1][0];
prod[1][0]=m1[1][0]*m2[0][0]+m1[1][1]*m2[1][0];
prod[0][1]=m1[0][0]*m2[0][1]+m1[0][1]*m2[1][1];
prod[1][1]=m1[1][0]*m2[0][1]+m1[1][1]*m2[1][1];
/* Escritura del resultado */
printf("nn El producto de las dos matrices es:
n");
for(i=0;i<2;i++)
{
printf(" | ");
for(j=0;j<2;j++)
{
printf("%5d",prod[i][j]);
}
printf(" | n");
}
}
Recuerda:
- Escribe el programa anterior utilizando tu
compilador. - Grábalo con el nombre Prog091.cpp en
TuCarpeta. - Ejecútalo un par o tres de veces
- Prog092
/* Prog092.cpp */
/* Programa que lee un sistema de 3
ecuaciones con
3 incógnitas
y escribe la matriz ampliada */
#include <stdio.h>
void main()
{
float a[3][4];
int j;
/* Introducción de datos
*/
printf("n Primera ecuaciónn
");
for (j=0;j<=3;j++)
{
if (j==3)
{
printf("tTérmino independiente:
t");
scanf("%f",&a[0][3]);
break;
};
printf("tCoeficiente de x%d:
t",j+1);
scanf("%f",&a[0][j]);
}
printf("n");
printf("n Segunda ecuaciónn
");
for (j=0;j<=3;j++)
{
if (j==3)
{
printf("tTérmino independiente:
t");
scanf("%f",&a[1][3]);
break;
};
printf("tCoeficiente de x%d:
t",j+1);
scanf("%f",&a[1][j]);
}
printf("n");
printf("n Tercera ecuaciónn
");
for (j=0;j<=3;j++)
{
if (j==3)
{
printf("tTérmino independiente:
t");
scanf("%f",&a[2][3]);
break;
};
printf("tCoeficiente de x%d:
t",j+1);
scanf("%f",&a[2][j]);
}
printf("n");
/* Escritura de la matriz ampliada */
printf("nn");
printf(" |");
for (j=0;j<=3;j++)
printf("t%7.2f",a[0][j]);
printf("n");
printf(" |");
for (j=0;j<=3;j++)
printf("t%7.2f",a[1][j]);
printf("n");
printf(" |");
for (j=0;j<=3;j++)
printf("t%7.2f",a[2][j]);
printf("n");
}
- Prog093
/* Prog093.cpp */
/* Programa que lee un sistema de 3 ecuaciones con 3
incógnitas
y resuelve el sistema por el método de
GAUSS
Supongo la existencia de coeficientes distintos de
cero
en las incógnitas
Supongo también que el sistema es Compatible
Determinado. */
#include <stdio.h>
void main()
{
float a[3][4];
int j,i,k;
float b;
float x[3],aux[3][4];
/* Introducción de datos */
printf("n Primera ecuaciónn
");
for (j=0;j<=3;j++)
{
if (j==3)
{
printf("tTérmino independiente:
t");
scanf("%f",&a[0][3]);
break;
};
printf("tCoeficiente de x%d:
t",j+1);
scanf("%f",&a[0][j]);
}
printf("n");
printf("n Segunda ecuaciónn
");
for (j=0;j<=3;j++)
{
if (j==3)
{
printf("tTérmino independiente:
t");
scanf("%f",&a[1][3]);
break;
};
printf("tCoeficiente de x%d:
t",j+1);
scanf("%f",&a[1][j]);
}
printf("n");
printf("n Tercera ecuaciónn
");
for (j=0;j<=3;j++)
{
if (j==3)
{
printf("tTérmino independiente:
t");
scanf("%f",&a[2][3]);
break;
};
printf("tCoeficiente de x%d:
t",j+1);
scanf("%f",&a[2][j]);
}
printf("n");
/* Escritura de la matriz ampliada */
printf("nn");
printf(" |");
for (j=0;j<=3;j++)
printf("t%7.2f",a[0][j]);
printf("n");
printf(" |");
for (j=0;j<=3;j++)
printf("t%7.2f",a[1][j]);
printf("n");
printf(" |");
for (j=0;j<=3;j++)
printf("t%7.2f",a[2][j]);
printf("n");
/* Método de GAUSS: hemos de conseguir una
matriz
triangular superior. */
for (i=0;i<=2;i++)
{
b=a[i][i];
// Observa que estoy suponiendo a[i][i] distinto de
0
for (j=i;j<=3;j++)
a[i][j]=a[i][j]/b;
for (j=i+1;j<=2;j++)
{
b=a[j][i];
for (k=i+1;k<=3;k++)
a[j][k]=a[j][k]-a[i][k]*b;
}
}
for (k=0;k<=2;k++)
{
i=2-k;
b=0;
for (j=i+1;j<=2;j++)
b=b+a[i][j]*x[j];
x[i]=a[i][3]-b;
}
a[1][0]=0;
a[2][0]=0;
a[2][1]=0;
/* Escribe la matriz resultante, Observa que
es
triangular superior. */
printf("nn");
printf(" |");
for (j=0;j<=3;j++)
printf("t%7.2f",a[0][j]);
printf("n");
printf(" |");
for (j=0;j<=3;j++)
printf("t%7.2f",a[1][j]);
printf("n");
printf(" |");
for (j=0;j<=3;j++)
printf("t%7.2f",a[2][j]);
printf("n");
printf("nnX1= %f X2= %f X3= %f
",x[0],x[1],x[2]);
}
Prueba el prog093 para los sistemas:
3x +2y –5z = -8
-2x –4y +z = -7
5x –4y +2z = 3
Si todo funciona correctamente nos sale: x= 1 ; y=2 ;
z=3
0x –5y +3z =-25
3x +0y –5z = 22
2x –7y +0z = -16
En este caso no funcionará porque a[0][0]=
0
1x +2y +3z = 4
2x +5y +3z = 6
2x +4y +5z = 3
Solución: x=-37 ; y=13 ; z=5
- Prog094
/* Prog094.cpp */
/* Programa que lee un sistema de 3 ecuaciones con 3
incógnitas
y resuelve el sistema por el método de GAUSS
*/
#include <stdio.h>
void main()
{
float a[3][4];
int j,i,k;
float b,aux;
float x[3];
/* Introducción de datos */
printf("n Primera ecuaciónn
");
for (j=0;j<=3;j++)
{
if (j==3)
{
printf("tTérmino independiente:
t");
scanf("%f",&a[0][3]);
break;
};
printf("tCoeficiente de x%d:
t",j+1);
scanf("%f",&a[0][j]);
}
printf("n");
printf("n Segunda ecuaciónn
");
for (j=0;j<=3;j++)
{
if (j==3)
{
printf("tTérmino independiente:
t");
scanf("%f",&a[1][3]);
break;
};
printf("tCoeficiente de x%d:
t",j+1);
scanf("%f",&a[1][j]);
}
printf("n");
printf("n Tercera ecuaciónn
");
for (j=0;j<=3;j++)
{
if (j==3)
{
printf("tTérmino independiente:
t");
scanf("%f",&a[2][3]);
break;
};
printf("tCoeficiente de x%d:
t",j+1);
scanf("%f",&a[2][j]);
}
printf("n");
/* Escritura de la matriz ampliada */
printf("nn");
printf(" |");
for (j=0;j<=3;j++)
printf("t%7.2f",a[0][j]);
printf("n");
printf(" |");
for (j=0;j<=3;j++)
printf("t%7.2f",a[1][j]);
printf("n");
printf(" |");
for (j=0;j<=3;j++)
printf("t%7.2f",a[2][j]);
printf("n");
/* Método de GAUSS: hemos de conseguir una
matriz
triangular superior. */
for (i=0;i<=2;i++)
{
if (a[i][i]==0)
{
j=i+1;
while (a[j][i]==0) j=j+1;
if (j==3)
{
printf("n ES UN SISTEMA
INCOMPATIBLE");
return;
}
for (k=0;k<=3;k++)
{
aux=a[i][k];
a[i][k]=a[j][k];
a[j][k]=aux;
}
};
b=a[i][i];
for (j=i;j<=3;j++)
a[i][j]=a[i][j]/b;
for (j=i+1;j<=2;j++)
{
b=a[j][i];
for (k=i+1;k<=3;k++)
a[j][k]=a[j][k]-a[i][k]*b;
}
}
for (k=0;k<=2;k++)
{
i=2-k;
b=0;
for (j=i+1;j<=2;j++)
b=b+a[i][j]*x[j];
x[i]=a[i][3]-b;
}
a[1][0]=0;
a[2][0]=0;
a[2][1]=0;
/* Escribe la matriz resultante, Observa que
es
triangular superior. */
printf("nn");
printf(" |");
for (j=0;j<=3;j++)
printf("t%7.2f",a[0][j]);
printf("n");
printf(" |");
for (j=0;j<=3;j++)
printf("t%7.2f",a[1][j]);
printf("n");
printf(" |");
for (j=0;j<=3;j++)
printf("t%7.2f",a[2][j]);
printf("n");
printf("nnX1= %f X2= %f X3= %f
",x[0],x[1],x[2]);
}
Prueba el prog094 para los sistemas:
3x +2y –5z = -8
-2x –4y +z = -7
5x –4y +2z = 3
Si todo funciona correctamente nos sale: x= 1 ; y=2 ;
z=3
0x –5y +3z =-25
3x +0y –5z = 22
2x –7y +0z = -16
Solución: x=-1 ; y=2 ; z= -5
1x +2y +3z = 4
2x +5y +3z = 6
2x +4y +5z = 3
Solución: x=-37 ; y=13 ; z=5
x + y + z = 3
2x –5y –z = 5
3x –4y +0z = 8
Es compatible indeterminado, una de x=2 ; y=-0,5 ; z=
1,5
x +y +z = 2
x –y +z = -3
2x +0y +2z = 1
Es un sistema incompatible.
- Prog095
/* Prog095.cpp */
/* Programa que transforma una matriz en
otra
equivalente, pero triangular superior,
por
el método de GAUSS */
#include <stdio.h>
void main()
{
float a[3][3];
int j,i,k;
float b,aux;
/* Introducción de datos */
printf("n Primera fila de la matrizn
");
for (j=0;j<=2;j++)
{
printf("tColumna %d:
t",j+1);
scanf("%f",&a[0][j]);
}
printf("n");
printf("n Segunda fila de la matrizn
");
for (j=0;j<=2;j++)
{
printf("tColumna %d:
t",j+1);
scanf("%f",&a[1][j]);
}
printf("n");
printf("n Tercera fila de la matrizn
");
for (j=0;j<=2;j++)
{
printf("tColumna %d:
t",j+1);
scanf("%f",&a[2][j]);
}
printf("n");
/* Escritura de la matriz */
printf("nn");
printf(" |");
for (j=0;j<=2;j++)
printf("t%7.2f",a[0][j]);
printf("n");
printf(" |");
for (j=0;j<=2;j++)
printf("t%7.2f",a[1][j]);
printf("n");
printf(" |");
for (j=0;j<=2;j++)
printf("t%7.2f",a[2][j]);
printf("n");
/* Método de GAUSS: hemos de conseguir una
matriz
triangular superior. */
for (i=0;i<=2;i++)
{
if (a[i][i]==0)
{
j=i+1;
while (a[j][i]==0) j=j+1;
if (j==2)
{
printf("nNo sé hacerlo porque hay muchos
ceros");
return;
}
for (k=0;k<=2;k++)
{
aux=a[i][k];
a[i][k]=a[j][k];
a[j][k]=aux;
}
};
b=a[i][i];
for (j=i+1;j<=2;j++)
{
b=a[j][i]/a[i][i];
for (k=i+1;k<=2;k++)
a[j][k]=a[j][k]-a[i][k]*b;
}
}
a[1][0]=0;
a[2][0]=0;
a[2][1]=0;
/* Escribe la matriz triangular superior
*/
printf("nn");
printf(" |");
for (j=0;j<=2;j++)
printf("t%7.2f",a[0][j]);
printf("n");
printf(" |");
for (j=0;j<=2;j++)
printf("t%7.2f",a[1][j]);
printf("n");
printf(" |");
for (j=0;j<=2;j++)
printf("t%7.2f",a[2][j]);
printf("n");
}
Matemáticamente no es del todo correcto, ya que
en el caso a[i][i]=0, permutamos las filas de la
matriz
Pruébalo para la matriz de las incógnitas
de los sistemas del programa anterior.
- Prog096
/* Prog096.cpp */
/* Programa que calcula el
determinante
por el método de GAUSS */
#include <stdio.h>
void main()
{
float a[3][3];
int j,i,k;
float b,aux,deter;
deter=1;
/* Introducción de datos */
printf("n Primera fila de la matrizn
");
for (j=0;j<=2;j++)
{
printf("tColumna %d:
t",j+1);
scanf("%f",&a[0][j]);
}
printf("n");
printf("n Segunda fila de la matrizn
");
for (j=0;j<=2;j++)
{
printf("tColumna %d:
t",j+1);
scanf("%f",&a[1][j]);
}
printf("n");
printf("n Tercera fila de la matrizn
");
for (j=0;j<=2;j++)
{
printf("tColumna %d:
t",j+1);
scanf("%f",&a[2][j]);
}
printf("n");
/* Escritura del determinante */
printf("nn");
printf(" |");
for (j=0;j<=2;j++)
printf("t%7.2f",a[0][j]);
printf("n");
printf(" |");
for (j=0;j<=2;j++)
printf("t%7.2f",a[1][j]);
printf("n");
printf(" |");
for (j=0;j<=2;j++)
printf("t%7.2f",a[2][j]);
printf("n");
/* Método de GAUSS: hemos de conseguir un
determinante
triangular superior. */
for (i=0;i<=2;i++)
{
if (a[i][i]==0)
{
j=i+1;
deter=-1;
while (a[j][i]==0) j=j+1;
if (j==2)
{
printf("nNo sé hacerlo porque hay muchos
ceros");
return;
}
for (k=0;k<=2;k++)
{
aux=a[i][k];
a[i][k]=a[j][k];
a[j][k]=aux;
}
};
b=a[i][i];
for (j=i+1;j<=2;j++)
{
b=a[j][i]/a[i][i];
for (k=i+1;k<=2;k++)
a[j][k]=a[j][k]-a[i][k]*b;
}
}
a[1][0]=0;
a[2][0]=0;
a[2][1]=0;
/* Escribe la matriz triangular superior
*/
printf("nn");
printf(" |");
for (j=0;j<=2;j++)
printf("t%7.2f",a[0][j]);
printf("n");
printf(" |");
for (j=0;j<=2;j++)
printf("t%7.2f",a[1][j]);
printf("n");
printf(" |");
for (j=0;j<=2;j++)
printf("t%7.2f",a[2][j]);
printf("n");
deter=deter*a[0][0]*a[1][1]*a[2][2];
printf("nEl determinante es
%f",deter);
}
Prueba els programa para los determinantes:
3 2 -5
-2 -4 1
5 -4 2
Solución: -134
0 -5 3
3 0 -5
2 -7 0
Solución: -13
1 2 3
2 5 3
2 4 5
Solución: -1
1 1 1
2 -5 -1
3 -4 0
Solución: 0
1 1 1
1 -1 1
2 0 2
Solución: 0
- Prog097
/* Prog097.cpp */
/* Programa que calcula un
determinante
de orden 'n' (n<=10) */
#include <stdio.h>
void main()
{
float a[10][10];
int j,i,k,n,s;
float b,aux,deter;
deter=1;
printf("nCálculo de un determinante de orden
? ");
scanf("%d",&n);
s=1;
/* Introducción de datos */
while (s<=n)
{
printf("n Fila %d del determinanten
",s);
for (j=0;j<=n-1;j++)
{
printf("tColumna %d:
t",j+1);
scanf("%f",&a[s-1][j]);
}
printf("n");
s++;
};
/* Escritura del determinante */
printf("nn");
for (s=0;s<=n-1;s++)
{
printf(" |");
for (j=0;j<=n-1;j++)
printf("t%7.2f",a[s][j]);
printf("n");
}
/* Método de GAUSS: hemos de conseguir un
determinante
triangular superior. */
for (i=0;i<=n-1;i++)
{
if (a[i][i]==0)
{
j=i+1;
deter=-1;
while (a[j][i]==0) j=j+1;
if (j==n-1)
{
printf("nNo sé hacerlo porque
hay muchos ceros");
return;
}
for (k=0;k<=n-1;k++)
{
aux=a[i][k];
a[i][k]=a[j][k];
a[j][k]=aux;
}
};
b=a[i][i];
for (j=i+1;j<=n-1;j++)
{
b=a[j][i]/a[i][i];
for (k=i+1;k<=n-1;k++)
a[j][k]=a[j][k]-a[i][k]*b;
}
}
for (i=1;i<=n-1;i++)
{
for (k=0;k<=n-1;k++)
{
j=i-1-k;
a[i][j]=0;
};
}
/* Escribe la matriz triangular superior
*/
printf("nn");
for (s=0;s<=n-1;s++)
{
printf(" |");
for (j=0;j<=n-1;j++)
printf("t%7.2f",a[s][j]);
printf("n");
}
for (i=0;i<=n-1;i++)
deter=deter*a[i][i];
printf("nEl determinante es
%f",deter);
}
Pruébalo para los determinantes:
5 2 -3 5
-1 1 2 6
1 0 -1 7
3 1 0 8
Solución: -112
-3 0 1 3
2 -1 2 -2
1 2 3 4
-1 5 -4 5
Solución: -31
0 -1 0 -1 0
1 2 0 -1 1
2 1 -3 -2 2
-1 1 3 2 3
5 1 4 -3 4
Solución: 183
- Direcciones de Memoria
Imaginemos que la memoria del
ordenador es como una fila de casillas en las que podemos
almacenar datos. En cada una de ellas podemos almacenar una
cantidad fija de información: 1 byte (8 bits = 8
ceros y unos que representan un carácter).
A cada una de estas casillas de nuestro ordenador, le
corresponde una dirección de memoria.
De esta forma, cuando en nuestro programa usamos una
variable, internamente lo que estamos haciendo es referirnos a
unas posiciones de memoria (es decir
un lugar de la memoria), que han sido reservadas cuando se
produjo la declaración de ésta.
- Prog098
/* Prog098.cpp */
#include <stdio.h>
void main()
{
int num;
num=78;
printf("n La dirección de memoria de la
variable num es %p",&num);
printf("n El valor de la variable num es
%d",num);
}
Graba el programa PROG098, en
TuCarpeta.
Ejecútalo varias veces.
Estudio del PROG098:
- La dirección de memoria de la variable
num, no es más que un numero en sistema de
numeración hexadecimal (por eso aparecen letras), que
indica el lugar de la memoria donde se guarda el valor de la
variable. - Debe quedar clara la diferencia entre valor de una
variable y su dirección de memoria. - Identificador de formato:
Para el valor de una variable int es
%d
Para la dirección de memoria es
%p
- Para acceder a una variable:
Nombre de la variable: accedemos a su valor
&nombre de la variable: accedemos a su
dirección de memoria.
Una dirección de memoria viene dada por un
número en sistema hexadecimal. Veamos como funciona
esto…Sistema Binario:
El sistema de numeración que nosotros
conocemos es el decimal (sistema de numeración
en base 10). Se llama decimal porque cualquier número
lo podemos expresar utilizando únicamente los 10
dígitos: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.El sistema
binario (sistema de numeración en base 2) utiliza
sólo dos dígitos: 0, 1El problema es cómo pasar del sistema binario
al decimal, para poder entendernos:Sea 1011 un número binario, para
hallar su equivalente en decimal hemos de hacer lo
siguiente:1011 = 1×20 + 1×21 +
0x22 + 1×23 = 1 + 2 + 8 = 11El número 1011 en base 2, es el
número 11 en base 10.1 Bit es un 1 o un 0, que representa en
informática, un circuito electrico por
el que pasa corriente (1) o no (0).1 Byte = 8 Bits por esta razón
a 1 byte se le llama también octeto
(8).1 Byte representa un carácter, se
alfabético, numérico o especial.Por ejemplo:
El Byte: 01000100 = 4 + 64 = 68 (en decimal)
corresponde al carácter D (código
ASCII= 68)El Byte: 00101101 = 45 (en decimal) corresponde al
carácter – (signo menos) y se corresponde
con el código ASCII=
45El byte: 00111001 = 57 corresponde al
carácter 9 (dígito 9) y se corresponde con el
código ASCII = 57Sistema hexadecimal:
El sistema hexadecimal utiliza 16 dígitos,
que son: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E,
FEl número 4A0 en sistema hexadecimal
será 1184 en sistema decimal,
porque:4A0 = 0x160 + Ax161 +
4×162 = 0x1 + 10×16 + 4×256 = 1184La utilidad del sistema hexadecimal está en
que utilizamos menos dígitos para expresar un
número mayor: El número 1184 en decimal ocupa 4
dígitos, encambio el mismo número en
hexadecimal (4A0) ocupa 3.Volviendo a nuestro lenguaje de
programación: en una variable hemos de distinguir
entre su valor (contenido de la celdilla o celdillas de
memoria) y su dirección de memoria (lugar de la
celdilla o celdillas = número en
hexadecimal).- Sistema de numeración
hexadecimal: - Punteros (pointers)
- Prog099
/* Prog099.cpp */
#include <stdio.h>
void main()
{
int *pint;
int *pint2;
printf("n Dirección de memoria de pint: %p
n",pint);
printf("n Dirección de memoria de pint2: %p
n",pint2);
*pint=10;
*pint2=25;
printf("n Valor de pint: %d
n",*pint);
printf("n Valor de pint2: %d
n",*pint2);
pint2=pint;
printf("n Atención acabo de igualar los dos
punteros n");
printf("n Dirección de memoria de pint: %p
n",pint);
printf("n Dirección de memoria de pint2: %p
n",pint2);
printf("n Valor de pint: %d
n",*pint);
printf("n Valor de pint2: %d
n",*pint2);
}
Estudio del PROG099:
- Un puntero (pointer) es una variable cuyo contenido
no es un valor, sino una dirección de
memoria. - La forma de declarar un puntero es igual que para
declarar una variable normal y corriente pero anteponiendo un
asterisco.
De esta forma: int *pint;
Int *pint2;
declaramos 2 punteros, es decir 2 direcciones de
memoria que contendran datos enteros (int).
- printf("n Dirección de memoria de pint: %p
n",pint);
Debido a que pint es un puntero, en la
instrucción anterior no hemos de anteponer &.
Aunque sí utilizar el identificador de formato
correspondiente (%p).
Está claro que:
int pepe;
printf("n Dirección de memoria de pepe: %p
n", &pepe);
sería equivalente.
- Para acceder al dato correspondiente a un puntero,
hemos de anteponer un asterisco. De esta forma:
*pint=10; sirve para asignar a la variable puntero
(pint) el valor entero 10. - Si observas detenidamente el resultado del programa
PROG099, conseguimos "eliminar" la dirección de
memoria de la variable pint2.
Vamos a intentar hacer un programa que haga lo mismo que
el anterior, pero sin utilizar punteros.
- Prog100
/* Prog100.cpp */
#include <stdio.h>
void main()
{
int pint;
int pint2;
printf("n Dirección de memoria de pint: %p
n",&pint);
printf("n Dirección de memoria de pint2: %p
n",&pint2);
pint=10;
pint2=25;
printf("n Valor de pint: %d
n",pint);
printf("n Valor de pint2: %d
n",pint2);
pint2=pint;
printf("n Atención acabo de igualar las dos
variables n");
printf("n Dirección de memoria de pint: %p
n",&pint);
printf("n Dirección de memoria de pint2: %p
n",&pint2);
printf("n Valor de pint: %d
n",pint);
printf("n Valor de pint2: %d
n",pint2);
}
Grábalo con el nombre PROG100
Ejecútalo varias veces y compáralo con el
PROG099
Estudio del PROG100:
- Básicamente el PROG100 es equivalente al
PROG099, pero con una diferencia fundamental: En el PROG099
igualamos el valor de dos variables, pero eliminando
físicamente una dirección de memoria. - En el PROG100 igualamos 2 variables pero continuamos
con dos variables de memoria. - Podríamos concluir: "el uso de punteros
permite ahorrar memoria". Próximamente veremos que el
uso de punteros (característico del lenguaje C),
sirve para bastantes más cosas. - Al escribir: int peps; el compilador reserva
una posición de memoria para albergar la
dirección de una variable "int" y de nombre
"*peps". Es decir: "peps" guardará la
dirección de memoria de la variable entera "*peps", se
dice que "peps" apunta a la variable entera
"*peps". - Al escribir:
int variab,*pint;
pint=&variab;
diremos que "pint" apunta a la variable
"variab".
Ante la orden "int variab" el compilador
"reserva" un grupo de
bits (los correspondientes a un número entero),
podríamos definir una variable como un conjunto de
bits. Encambio "pint" es una dirección de
memoria, en nuestro ejemplo: la dirección de
memoria de la variable "variab"
(pint=&variab).
- Si consideras el siguiente programa:
/* Prog100b.cpp */
#include <stdio.h>
void main()
{
char var1;
char *pchar;
pchar=&var1;
for
(var1=’a’;var1<=’z’;var1++)
printf("%c",*pchar);
}
Evidentemente seria equivalente en lugar de
"printf("%c",*pchar)" escribir
"printf("%c",var1)"
Observa que en la línea: pchar=&var1
inicializamos el puntero (asignamos a pchar la
dirección de var1) y automáticamente
inicializamos "*pchar" (asignamos a "*pchar" la variable
"var1"), aunque el valor de var1 no lo asignamos hasta
for(var1=’a’; …)
- Funciones Recursivas
- Prog101
/* Prog101.cpp */
#include <stdio.h>
long fact(int n);
void main()
{
int num;
printf("n Introduce un número entero:
");
scanf("%d",&num);
printf("n El factorial de %d es %ld",
num,fact(num));
}
long fact(int n)
{
if (n<=1) return 1;
else return n*fact(n-1);
}
Graba el programa con el nombre PROG101, en
TuCarpeta.
Ejecútalo varias veces. Probablemente el programa
no funcionará para valores mayores que 16 (piensa que es
una función que crece muy aprisa).
Estudio del PROG101:
Una función recursiva es una función que
se llama a sí misma: observa que en el "interior" de la
función fact(), hay una llamada a sí misma:
n*fact(n-1)
- Prog102
/* Prog102.cpp */
/* Sucesión de Fibonacci (forma
recursiva)
0,1,1,2,3,5,8,13,…. */
#include <stdio.h>
int fibona(int v);
void main()
{
int r,valor;
printf("0");printf("n1");printf("n1");
for(valor=1;valor<=20;valor++)
{
r=fibona(valor);
printf("n%d",r);
}
}
int fibona(int v)
{
if((v==0)||(v==-1)) return 1;
else
return fibona(v-1)+fibona(v-2);
}
- Punteros y Funciones
- Prog103
/* Prog103.cpp */
#include <stdio.h>
void main()
{
int v1,v2,aux;
printf("n Primer valor ? ");
scanf("%d",&v1);
printf("n Segundo valor ? ");
scanf("%d",&v2);
aux=v1;
v1=v2;
v2=aux;
printf("nn Nuevo primer valor:
%d",v1);
printf("nn Nuevo segundo valor:
%d",v2);
}
Estudio del PROG103:
- El programa lo que hace es simplemente intercambiar
los valores de 2 variables - Recuerda (ya lo hicimos en el PROG088), que el
intercambio de valores se consigue gracias al uso de una
variable auxiliar:
aux=v1;
v1=v2;
v2=aux;
v1 adquirirá el valor de v2 y v2 tomará
el valor de v1.
- El problema del "intercambio" se encuentra en el caso
de una función, como veremos a
continuación.
Se trata de hacer el programa anterior, pero el proceso de
"intercambio" lo pondremos en una función.
- Prog104
/* Prog104.cpp */
#include <stdio.h>
void cambiar(int v1,int v2);
void main()
{
int v1,v2,aux;
printf("n Primer valor ? ");
scanf("%d",&v1);
printf("n Segundo valor ? ");
scanf("%d",&v2);
cambiar(v1,v2);
printf("nn Nuevo primer valor:
%d",v1);
printf("nn Nuevo segundo valor:
%d",v2);
}
void cambiar(int v1,int v2)
{
int aux;
aux=v1;
v1=v2;
v2=aux;
}
Si todo funciona correctamente verás que el
programa PROG104 no funciona, es decir: "no se
intercambian los dos valores"..
Vamos a solucionar el problema, se trata de hacer el
mismo programa PROG104, pero trabajando con
punteros.
- Prog105
/* Prog105.cpp */
#include <stdio.h>
void cambiar(int *pv1,int *pv2);
void main()
{
int v1,v2,aux;
printf("n Primer valor ? ");
scanf("%d",&v1);
printf("n Segundo valor ? ");
scanf("%d",&v2);
cambiar(&v1,&v2);
printf("nn Nuevo primer valor:
%d",v1);
printf("nn Nuevo segundo valor:
%d",v2);
}
void cambiar(int *pv1,int *pv2)
{
int aux;
aux=*pv1;
*pv1=*pv2;
*pv2=aux;
}
Graba el programa con el nombre PROG105, en
TuCarpeta.
Ejecútalo varias veces.
Observa que el uso de punteros no sirve sólo para
ahorrar memoria.
- Punteros y Arrays
- Prog106
/* Prog106.cpp */
#include <stdio.h>
void main()
{
int i,t[5],*pun;
for(i=0;i<5;i++) t[i]=i;
printf("n Listado del array: n");
for(i=0;i<5;i++)
printf("n%d",t[i]);
printf("n Listado del array, pero a través
de punteros: n");
for(i=0;i<5;i++)
{
pun=t+i;
printf("%dn",*pun);
}
}
Estudio del PROG106:
- El nombre de un array (t, en nuestro caso) es
sinónimo de la dirección de memoria del primer
byte de sus elementos. Por lo tanto: pun=t+i al variar
i= 0, 1, 2, 3, 4 no es más que las direcciones de
memoria de los 5 valores del array.
- Prog107
/* Prog107.cpp */
#include <stdio.h>
void main()
{
int i,t[5],*pun;
for(i=0;i<5;i++) t[i]=i;
printf("n Listado del array: n");
for(i=0;i<5;i++)
printf("n%d",t[i]);
pun=&t[4];
printf("n Array en orden inverso:
n");
for(i=0;i<5;i++)
{
printf("%dn",*pun);
pun=pun-1;
}
}
- Prog108
/* Prog108.cpp */
#include <stdio.h>
void main()
{
int i,j,mat[5][5];
for(i=0;i<5;i++)
for(j=0;j<5;j++)
mat[i][j]=5*i+j;
printf("n Listado de la
matriz:n");
for(i=0;i<5;i++)
for(j=0;j<5;j++)
printf("%d-",mat[i][j]);
printf("n Listado de la matriz pero utilizando
punteros: n");
for(i=0;i<5;i++)
{
for(j=0;j<5;j++)
printf("%d-",*(*(mat+i)+j));
printf("n");
}
}
Compara el PROG106 y el PROG108, parecen complicados
¿verdad?. Ciertamente que sí, pero debes tener en
cuenta las siguientes reglas:
- El nombre de un array unidimensional es un
sinónimo de la dirección de memoria de su primer
byte. - El contenido del elemento "i" de un array
unidimensional de nombre "pepe" se obtiene como
*(pepe+i) - Una tabla bidimensional no es sino una matriz
unidimensional cuyos elementos son, a su vez, arrays
unidimensionales.
- Prog109
/* Prog109.cpp */
#include <stdio.h>
float invertir(float *numero);
void main()
{
float i;
printf("n Escribe un número: ");
scanf("%f",&i);
if (invertir(&i) != 0) printf("n El inverso es
%f",i);
else printf("n No tiene inverso");
}
float invertir(float *numero)
{
if(*numero==0) return 0;
else
{
*numero=1/(*numero);
return *numero;
}
}
- Prog110
/* Prog110.cpp */
/* Ejemplo de funciones por valor y por referencia
(dirección de memoria) */
/* Calcula dos veces el procentaje de gastos, la
primera vez
utilizando una función por valor y la segunda
por referencia (punteros) */
#include<stdio.h>
#include <conio.h>
void porcentaje_xvalor(float ingreso, float
egreso);
void porcentaje_xref(float *ingreso,float
*egreso);
void main()
{
float entrada,salida;
clrscr();
printf("Entradas: ");
scanf("%f",&entrada);
printf("Salidas: ");
scanf("%f",&salida);
porcentaje_xvalor(entrada,salida); /*Llamada a la
función porcentaje
utilizando paso de parámetros por
valor*/
printf("nn");
porcentaje_xref(&entrada,&salida);
/*Utilización de la función
porcentaje
con paso de parámetros por
referencia*/
getch();
}
void porcentaje_xvalor(float ingreso, float
egreso)
{
egreso=((egreso/ingreso)*100);
printf("Usted gasta el %.2f por ciento de lo que
gana",egreso);
}
void porcentaje_xref(float *ingreso,float
*egreso)
{
*egreso=(((*egreso)/(*ingreso))*100);
printf("Usted gasta el %.2f por ciento de lo que
gana",*egreso);
}
- Variables dinámicas
Hasta ahora teníamos una serie de variables que
declaramos al principio del programa o de cada función.
Estas variables que reciben el nombre de estáticas,
tienen un tamaño asignado desde el momento en que se crea
el programa.
Pensemos en la "programación de una agenda": tenemos una
serie de fichas y nos
interesa añadir más. Si pensamos en variables
estáticas, prepararíamos la agenda para 1000
fichas aunque creamos que no vamos a pasar de 300. Está
claro que esto es desperdiciar memória.
El uso de variables dinámicas se basa en
reservar un poco de memoria para cada nuevo elemento que nos haga
falta y enlazarlo a los que ya teníamos. Cuando queramos
borrar un elemento, enlazamos el anterior a él con el
posterior a él y liberamos la memoria que estaba
ocupando.
Así que para seguir, necesitamos saber
cómo reservar memoria y cómo liberarla.
Y entre otras cosas necesitamos "los
punteros"….
Recordemos:
int num; // "num" es un número entero
int *pos; // "pos" es un puntero a entero =
dirección de memoria en la que podemos guardar
// un entero.
num=1; // ahora "num" vale 1
pos=1000; // "pos" ahora es la dirección 1000. Es
peligroso ya que en la dirección de memoria
// que contiene "pos" no sabemoa lo que hay y podemos
provocar una catástrofe.
*pos=25; // en la dirección de memoria de "pos"
guardamos un 25
pos=# // la variable "pos" contiene la
dirección de memoria de la variable "num".
En la práctica "pedimos" al compilador que nos
reserve un poco de memoria donde él crea adecuado,
utilizando la función "malloc", que se encuentra en
el fichero stdlib.h
Una vez hemos utilizado esta memoria es conveniente
liberarla, utilizando la función "free"
Veamos:
- Prog111
/* Prog111.cpp */
#include <stdio.h>
#include <stdlib.h>
int num;
int *pos;
void main()
{
printf("num vale: %d
(arbitrario)n",num);
printf("La dirección pos es: %p
(arbitrario)n",pos);
num=1;
printf("num vale: %d (fijado)n",num);
pos=(int *) malloc(sizeof(int)); /* reservamos
espacio */
printf("La dirección pos es: %p
(asignado)n",pos);
printf("El contenido de pos es: %d
(arbitrario)n",*pos);
*pos=25;
printf("El contenido de pos es: %d
(fijado)n",*pos);
free(pos);
pos=#
printf("Y ahora el contenido de pos es: %d (valor de
num)n",*pos);
}
free(pos);
libera la memoria que ocupaba "pos".
pos=(int *) malloc(sizeof(int));
sizeof(int): espacio a reservar, como el tamaño
debe corresponder a un entero. sizeof(int) corresponde al
tamaño de un entero.
"malloc" nos devuelve un puntero sin tipo (void *), como
queremos guardar un dato entero, hemos de hacer una
conversión de tipos: de "puntero sin tipo (void *)"
a "puntero a entero (int *)".
Una vez ejecutado el programa, observemos:
- Inicialmente "num" vale 0 (no podemos fiarnos de que
siempre sea así, ya que no lo hemos inicializado
nosotros) - Inicialmente "pos" es 0. Es un puntero nulo, para el
cual no se ha asignado un espacio en memoria.
- Prog112
/* Prog112.cpp */
/* Creación de un array dinámicamente
*/
#include <stdio.h>
#include <stdlib.h>
int *num; /* puntero a numero entero
*/
int *temporal; /* temporal, para recorrer el array
*/
int i; /* para bucles */
void main()
{
/* Reservamos espacio para 10 números (array
dinámico) */
num=(int *) malloc(10*sizeof(int));
for(i=0;i<10;i++) /* Recorremos el array
*/
num[i]=i*2; /* Dando valores */
printf("La dirección de comienzo del array
es: %pn",num);
printf("Valores del array: ");
for(i=0;i<10;i++) /* Recorremos el array
*/
printf(" %d ",num[i]); /* mostrando los valores
*/
printf("n Valores del array (como puntero):
");
temporal=num;
for(i=0;i<10;i++) /* Recorremos como puntero
*/
printf(" %d ",*temporal++); /* mostrando los
valores y
aumentando */
free(num); /* Liberamos lo reservado
*/
}
Como se ve, en "C" hay muy poca diferencia entre arrays
y punteros: hemos declarado "num" como un puntero, pero hemos
reservado espacio para más de un dato, y hemos podido
recorrerlo como si hubiésemos definido: int
num[10];
- Cadenas de texto
Una cadena de texto en "C"
es un array de caracteres
Como a todo array, se le puede reservar espacio
estáticamente o dinámicamente:
Estáticamente: char texto[80];
Dinámicamente: char *texto; reservando espacio
con "malloc" cuando nos haga falta.
De todas formas una cadena de caracteres siempre
terminará con un carácter nulo ()
Es decir:
Si necesitamos 7 letras para un teléfono: char telefono[8];
7 letras del teléfono +
Para copiar el valor de una cadena de texto en otra, no
podemos hacer: texto1 = texto2, porque estaríamos
igualando dos punteros. En vez de eso, debemos usar una
función de biblioteca: strcpy que se encuentra en
string.h
Strcpy(destino, origen);
El problema está en que en la cadena destino haya
suficiente espacio reservado para copiar lo que
queremos:
- Si queremos copiar sólo los primeros "n" bytes
de origen, usamos:
strncpy(destino,origen,n);
- Para añadir una cadena al final de otra
(concatenarla), usamos:
strcat(origen,destino); - Para comparar dos cadenas alfabéticamente
(para ver si son iguales o para ordenarlas, por ejemplo),
usamos:
strcmp(cad1,cad2);
= 0 si las cadenas son iguales.
<0 si cad1<cad2
>0 si cad1>cad2
- Según el compilador tenemos:
strupr(cadena); que convierte la cadena a
mayúsculas - Prog113
/* Prog113.cpp */
/* Cadenas de texto */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char texto1[80]="Hola"; /* Cadena Estática
*/
char *texto2; /* Cadena Dinámica */
void main()
{
/* Reservo espacio para la cadena dinámica
*/
texto2=(char *) malloc
(70*sizeof(char));
strcpy(texto2,"Adios"); /* Le doy un valor
*/
puts(texto1);
puts(texto2); /* Escribo las dos */
strncpy(texto1,texto2,3); /* copio las
3
primeras
letras */
puts(texto1);
strcat(texto1,texto2); /* añado text2 al
final */
puts(texto1);
printf("Si las comparamos obtenemos:
%d",strcmp(texto1,texto2));
printf("(Numero negativo: texto1 es menor)
n");
printf("La longitud de la primera es %d n",
strlen(texto1));
printf("En mayúsculas es %s
n",strupr(texto1));
free(texto2);
}
- Prog114
/* Prog114.cpp */
/* Programa que analiza lo que escribimos:
dígitos numéricos
o caracteres alfabéticos. */
#include <stdio.h>
#include<string.h>
#include <stdlib.h>
#include <conio.h>
int menu();
/* función que hace aparecer un menú
con dos opciones:
1: sólo números, 2: sólo letras.
Devuelve 1 o 2 */
int numeros();
/* función que lee dígitos
numéricos en forma de caracteres
y devuelve el valor en entero. */
void captura(char palabra[]);
/* función que lee en forma de caracteres y
analiza si
son letras */
void main()
{
int cifra;
char word[20];
clrscr();
switch(menu())
{
case 1: cifra=numeros();
printf("n%d",cifra);
break;
case 2: captura(word);
printf("n%s",word);
break;
default: exit(0);
}
getch();
}
void captura(char palabra[])
{
char *letra;
char
alfabeto[]="ABCDEFGHIJKLMNÑOPQRSTUVWXYZabcdefghijklmnñopqrstuvwxyz";
int i;
palabra[0]='';
clrscr();
do
{
*letra=getch();
for (i=0;i<=53;i++)
{
if (alfabeto[i]==*letra)
{
printf("%c",*letra);
strcat(palabra,letra);
/* la función "strcat" añade "letra"
a "palabra" y añade
al final el caracter nulo. Se encuentra en
<string.h> */
break;
}
}
}while((*letra!=13) &&
(strlen(palabra)<20));
}
int numeros()
{
char cadena[10];
char car='';
int i=0;
int cantidad;
do
{
car=getch();
switch(car)
{
case'0': cadena[i]=car;
printf("%c",car);
break;
case'1': cadena[i]=car;
printf("%c",car);
break;
case'2': cadena[i]=car;
printf("%c",car);
break;
case'3': cadena[i]=car;
printf("%c",car);
break;
case'4': cadena[i]=car;
printf("%c",car);
break;
case'5': cadena[i]=car;
printf("%c",car);
break;
case'6': cadena[i]=car;
printf("%c",car);
break;
case'7': cadena[i]=car;
printf("%c",car);
break;
case'8': cadena[i]=car;
printf("%c",car);
break;
case'9': cadena[i]=car;
printf("%c",car);
break;
default: i–;
break;
}
i++;
}while((car!=13) && (i<5));
cantidad=atoi(cadena);
/* la función "atoi" devuelve el
número entero correspondiente
a "cadena". Se encuentra en <stdlib.h>
*/
return(cantidad);
}
int menu()
{
int numero;
printf("Escoge una opción:n");
printf("1. Escribir sólo
númerosn");
printf("2. Escribir únicamente
letrasn");
printf("Opción: ");
scanf(" %d",&numero);
return(numero);
}
- Prog115
/* Prog115.cpp */
/* Programa que demuestra el procedimiento
copia el cual,
copia una cadena en otra*/
#include<string.h>
#include <conio.h>
#include<stdio.h>
char *copia(char *cad1,char *cad2);
void main()
{
char palabra1[10];
char palabra2[10];
char palabra3[20];
printf("palabra1= ");
scanf("%s",palabra1);
printf("palabra2= ");
scanf("%s",palabra2);
copia(palabra2,palabra1);
printf("palabra1+palabra2=
%s",palabra1);
getch();
}
char *copia(char *cad1, char *cad2)
{
char *inicio;
int i;
inicio=cad2;
while(*cad2!='')
cad2++;
while(*cad1!='')
{
*cad2=*cad1;
cad2++;
cad1++;
}
*cad2='';
cad2=inicio;
}
- Estructuras (o registros)
Una estructura es
un nuevo tipo de dato, que consta de una agrupación de
datos (como los arrays), pero de distinto tipo (a diferencia de
los array).
- Prog116
/* Prog116.cpp */
/* Uso de "estructuras". */
#include <stdio.h>
struct {
char inicial;
int edad;
float nota;
} persona;
void main()
{
persona.edad=20;
printf("La edad es
%d",persona.edad);
}
AUTOEVALUACIÓN 4
- Haz un programa para calcular el área de un
círculo, utilizando una constante simbólica
para el número PI. Graba el programa con el nombre
EVAL4AGraba el programa con el nombre
EVAL4B. - Haz un programa que "simula una tirada aleatoria de 3
dados de parchís" utilizano la función
rand(). - Utilizando la función rand() haz un
programa que simule una jugada de los dados de póker.
Graba el programa con el nombre EVAL4C. - Utilizando matrices bidimensionales haz un programa
que resuelva por el método de Cramer un sistema de 2
ecuaciones con 2 incógnitas. Graba el programa con el
nombre EVAL4D. - Utilizando matrices bidimensionales haz un programa
que calcule la media de las temperaturas máxima y
mínima de una semana para un "lugar determinado". Graba
el programa con el nombre EVAL4E. - Haz un programa que nos pida los elementos de una
matriz de orden 4 y por último la escribe en pantalla
(bien escrita). Graba el programa con el nombre
EVAL4F. - Haz un programa que al escribir un número en
base 2 o base 3 lo escribe en decimal. Graba el programa con el
nombre EVAL4G. - Haz un programa que multiplique 3 números y
nos muestre la dirección de memoria de cada uno de los 3
números y también del producto. Graba el programa
con el nombre EVAL4H. - Haz un programa igual que el anterior pero utilizando
punteros (EVAL4I).3n+1
——
2n-1 utilizando una función recursiva
(EVAL4J). - Haz un programa que calcule los 20 primeros
términos de la sucesión de término
general: - Haz un programa igual que el EVAL4D pero
utilizando una función con punteros que calcule los
determinantes de orden 2 (EVAL4K). - Haz un programa que escriba el vector (1, 2, 6, 24,
120, …) de 7 componentes utilizando punteros
(EVAL4L).0 1 1 1 1
0 0 1 1 1
0 0 0 1 1
0 0 0 0 1
utilizando punteros (EVAL4M).
- Haz un programa que escriba la matriz: 1 1 1 1
1 - Haz un programa que calcule el cubo de un
número, utilizando una función de argumento un
puntero (EVAL4N). - Haz un programa que calcule la raiz cuarta de un
número, utilizando una función con argumento un
puntero (EVAL4O).
Hasta aquí, la versión no registrada
del manual.
Si deseas la parte que falta, es
decir:
V.- Entrada y Salida por Ficheros 131
VI.- El lenguaje de
programación C++ 171
VII.- Arrays, Punteros y Funciones en C++ 187
VIII.- Programación
Orientada a Objetos 205
Apéndice A: Funcionamiento básico del
Turbo C++ 3.1 223
Apéndice B: Instalación y Funcionamiento
básico del DJGPP 2.1 227
Apéndice C: La "moderna" P.O.O (Visual C++
6.0) 229
Debes adquirir la versión registrada, es decir
entera.
Es muy fácil, has de hacer lo
siguiente:
- Rellena el siguiente formulario con tus
datos: A mi dirección que
es: F.V.c) Valencia 21-25, 2º ,
4ª08915 – Badalona
(Barcelona)España
- Envíame el formulario anterior por correo
ordinario junto con un "billete" (lo que consideres justo por
un disquete, gastos de manipulación, envío y
"estímulo por mi parte para que continue colgando en
Internet, mis
manuales"). - A vuelta de correo recibirás en tu
dirección, un disquete con la versión completa
del manual "C/C++ (Manual FV)".
Autor:
Gabriel Mendoza
Página anterior | Volver al principio del trabajo | Página siguiente |