Descargar

Programación en C/C++ (Manual FV) (página 4)

Enviado por Gabriel Mendoza


Partes: 1, 2, 3, 4

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

  1. Haz un programa que calcule el producto vectorial de 2 vectores del espacio.
  2. Graba el programa con el nombre EVAL3A.

    Graba el programa con el nombre EVAL3B.

  3. 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.

  4. 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)
  5. 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

  1. 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.
  1. Haz un programa de nombre EVAL3F que sirva para elevar al cubo un número, pero utilizando una función.
  2. 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.
  3. Haz un programa de nombre EVAL3H que transforme un número en base 10 a base 4 y 5
  4. 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.
  5. Haz un programa de nombre EVAL3J que construya el triángulo de Tartaglia o de Pascal.

IV.- Punteros y Arrays

  1. 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.
  1. 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));

}

  1. 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

  1. 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.

  1. 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, 1

    El 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 = 11

    El 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= 45

    El byte: 00111001 = 57 corresponde al carácter 9 (dígito 9) y se corresponde con el código ASCII = 57

    Sistema 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, F

    El número 4A0 en sistema hexadecimal será 1184 en sistema decimal, porque:

    4A0 = 0x160 + Ax161 + 4×162 = 0x1 + 10×16 + 4×256 = 1184

    La 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).

  2. Sistema de numeración hexadecimal:
  3. 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’; …)

  1. 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);

}

  1. 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.

  1. 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:

  1. El nombre de un array unidimensional es un sinónimo de la dirección de memoria de su primer byte.
  2. El contenido del elemento "i" de un array unidimensional de nombre "pepe" se obtiene como *(pepe+i)
  3. 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);

}

  1. 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=&num; // 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=&num;

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];

  1. 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;

}

  1. 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

  1. 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 EVAL4A

    Graba el programa con el nombre EVAL4B.

  2. Haz un programa que "simula una tirada aleatoria de 3 dados de parchís" utilizano la función rand().
  3. 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.
  4. 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.
  5. 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.
  6. 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.
  7. 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.
  8. 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.
  9. Haz un programa igual que el anterior pero utilizando punteros (EVAL4I).

    3n+1

    ——

    2n-1 utilizando una función recursiva (EVAL4J).

  10. Haz un programa que calcule los 20 primeros términos de la sucesión de término general:
  11. Haz un programa igual que el EVAL4D pero utilizando una función con punteros que calcule los determinantes de orden 2 (EVAL4K).
  12. 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).

  13. Haz un programa que escriba la matriz: 1 1 1 1 1
  14. Haz un programa que calcule el cubo de un número, utilizando una función de argumento un puntero (EVAL4N).
  15. 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:

  1. Rellena el siguiente formulario con tus datos:
  2. A mi dirección que es: F.V.

    c) Valencia 21-25, 2º , 4ª

    08915 – Badalona (Barcelona)

    España

  3. 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").
  4. 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

Partes: 1, 2, 3, 4
 Página anterior Volver al principio del trabajoPágina siguiente