Está en la página 1de 19

Fundamentos de Programación

Fundamentación Teórica de Lenguaje C

Operador dirección-de
6AB34
El operador & ( dirección de) da la dirección de su variable. Por ejemplo,
a
int a = 7; // la variable entera 'a' almacena el valor 7 7 a
printf("dirección de memoria= %p, dato= %d\n", &a, a);

6AB36
ya utilizábamos el &
scanf(“%d”,&a);

int 2 byte
char 1byte
float 4 byte

unsigned int desde 0 hasta el 65535


en un entero – 32767 hasta el 32768
int ocupa un espacio de memoria 2 byte
6AB34 6AB36
RAM
1byte 1byte 1byte 1byte 1byte
00000000 00000111

7(sistema decimal) = 00000000 00000111 (sistema binario)

Fundamentos de Programación | Ing. Patricio Vinueza


Sistema decimal
65 2
1 32 2
0 16 2
0 8 2
0 4 2
0 2 2
0 1
1000001
00000000 01000001

Sistema decimal
7 2
1 3 2
1 1
00000000 00000111

El resultado desde el punto de vista gráfico puede verlo en la. figura siguiente. La figura
representa un segmento de memoria de n bytes. En este segmento localizamos el entero 7
de dos bytes de longitud, en la dirección 13162. La variable a representa al valor 7 y &a
(dirección de a; esto es, donde se localiza a) es 13162.
6AB34

7
a
6AB34
a
int a;
int *pa; 18
pa
a = 10;
pa = 12; //esto es error
6AB34
pa = &a; esto es correcto

a = 20;
*pa = 18;
printf(“%d”,a); //me muestra 18
printf(“%d”,*pa); //me muestra 18
printf(“%p”,&a); //me muestra 6AB34
printf(“%p”,pa); //me muestra 6AB34

Fundamentos de Programación | Ing. Patricio Vinueza


& operador de dirección
* operador de indireccion

Operador de indirección

El operador *(indirección) accede a un valor indirectamente a través de un puntero. El


resultado es el valor direccionado (apuntado) por el operando.

Un puntero es una variable capaz de contener una dirección de memoria que indica dónde
se localiza un objeto de un tipo especificado (por ejemplo, un entero). La sintaxis para
definir un puntero es:

tipo *identificador;

donde tipo es el tipo del objeto apuntado e identificador el nombre del puntero.

El siguiente ejemplo declara un puntero px a un valor entero x y después asigna este valor
al entero y.
px x y
7 7
int main()
{
int *px, x = 7, y= 0; // px es un puntero a un valor entero
px = &x; // en el puntero px se almacena la dirección de x
y= *px; //a la variable y se le asigna el valor localizado en la dirección
// almacenada en px
}

Fundamentos de Programación | Ing. Patricio Vinueza


Suponiendo que la dirección de x es 13162, el resultado expresado de una forma gráfica es
el siguiente:
13162

13162

13162 7 7

px x y

Apunta

Lo que indica que el contenido de px (*px) es 7. La sentencia y = *px se lee "y igual al
contenido de px". De una forma más explícita diríamos "y igual al contenido de la dirección
dada por px".

Declaración de una función

La declaración de una función, también conocida como prototipo de la función, indica


cuántos parámetros tiene la función y de qué tipo son, así como el tipo del valor retornado.
Su sintaxis es:

tipo-resultado nombre-función ([lista de parámetros]);

El prototipo de una función es una plantilla que se utiliza para asegurar que una sentencia
de invocación escrita antes de la definición de la función, es correcta: esto es, que son
especificados los argumentos adecuados y que el valor retornado se trata correctamente.

Este chequeo de tipos y número de argumentos permite detectar durante la compilación si


se ha cometido algún error. Por ejemplo, la siguiente sentencia declara la función convertir
para indicar que cuando sea invocada tiene que recibir un argumento entero y que cuando
finalice su ejecución, retornará un valor real.
float convertir(int e);

En conclusión, la declaración de una función da características de la misma, pero no define


el proceso que realiza.

Fundamentos de Programación | Ing. Patricio Vinueza


Una función puede ser declarada implícitamente o explícitamente. La declaración implícita
se da cuando la función es llamada y no existe una declaración previa (prototipo de la
función). En este caso, C, por defecto, construye una función prototipo. Esto obliga a que la
función se la defina o desarrolle antes del main. Por ello, se recomienda realizar siempre
una declaración explícita de la función.

La declaración explícita, especifica el número y el tipo de los argumentos de la función, así


como el tipo del valor retomado.

La lista de parámetros normalmente consiste en una lista de identificadores con sus tipos,
separados por comas. En el caso de que se trate del prototipo de una función, se pueden
omitir los identificadores. Por ejemplo:

float funcion_x(int , float , char );

En cambio, si se especifican, su ámbito queda restringido a la propia declaración; esto es,


no son accesibles en otra parte. Por ejemplo, en la declaración siguiente, a, b y c no son
accesibles en ninguna otra parte.

float funcion_x(int a, float b, char e);

De lo expuesto se deduce que los identificadores utilizados en la declaración de la función


y los utilizados después en la definición de la misma función no necesariamente tienen que
ser los mismos.

Para asegurar la portabilidad de los programas, se puede utilizar el tipo void para especificar
que una función no acepta argumentos, ya que, a diferencia de C++, en el lenguaje C
estándar la ausencia de parámetros y la no especificación de void indica cualquier número
y tipo de argumentos. Según esto, las declaraciones siguientes tienen la misma validez,
aunque con significados diferentes.

float fnEscribir(void); /* función sin argumentos*/


float fnEscribir(); /* función con cualquier número y tipo de argumentos*/

Las declaraciones de las funciones pertenecientes a la biblioteca estándar de C, como printf,


son proporcionadas por los ficheros de cabecera o ficheros .h. Por eso, cuando un programa
utiliza, por ejemplo, la función printf observará que se incluye el fichero de cabecera stdio.h.

#include <stdio.h>

Fundamentos de Programación | Ing. Patricio Vinueza


Al especificar la sintaxis de las funciones de la biblioteca de C, también se indica el fichero
de cabecera donde está declarada.

Definición de una función

La definición de una función consta de una cabecera de función y del cuerpo de la función
encerrado entre llaves.

tipo-resultado nombre-función ([parámetros formales])


{

declaraciones de variables locales;


sentencias;
[return [(]expresión[)] ];
}

Las variables declaradas en el cuerpo de la función son locales y por definición solamente
son accesibles dentro del mismo.

El tipo del resultado especifica qué tipo de datos retorna la función. Este, puede ser
cualquier tipo fundamental, o tipo definido por el usuario, pero no puede ser un array o una
función. Si no se especifica, se supone que es int. El resultado de una función es devuelto a
la sentencia de llamada, por medio de la sentencia:
return [()expresión[));

Esta sentencia puede ser o no la última y puede aparecer más de una vez en el cuerpo de la
función. En el caso de que la función no retorne un valor, se puede omitir o especificar
simplemente return. Por ejemplo,

void fnEscribir()
{
// …
return;
}

Los parámetros formales de una función son las variables que reciben los valores de los
argumentos especificados en la llamada a la función. Consisten en una lista de
identificadores con sus tipos, separados por comas. A continuación puede ver un ejemplo:

float convertir(int gcent) /* cabecera de la función*/


{ /* cuerpo de la función*/
float gfahr;

Fundamentos de Programación | Ing. Patricio Vinueza


gfahr = (float)9 / (float)5 * gcent + 32;
return (gfahr); /* valor retornado*/
}

Llamada a una función

Para ejecutar una función hay que llamarla. La llamada a una función consta del nombre de
la misma y de una lista de argumentos, denominados parámetros actuales, encerrados
entre paréntesis y separados por comas. Por ejemplo:

/* Se llama a la función convertir*/


GradosFahrenheit = convertir(nGradosCentigrados);

Pasando argumentos a las funciones

Cuando se llama a una función, el valor del primer argumento actual es pasado al primer
parámetro formal, el valor del segundo argumento actual es pasado al segundo parámetro
formal y así sucesivamente. Por defecto, todos los argumentos, excepto los arrays, son
pasados por valor. Esto significa que a la función se pasa una copia del valor del argumento,
no su dirección. Esto hace que la función invocada, no pueda alterar las variables que
contienen los valores pasados.

En el ejemplo anterior, cuando se llama a la función convertir, el parámetro formal gcent


recibe el valor del parámetro actual nGradosCentigrados.

En el siguiente ejemplo, puede observar que la función main llama a la función intercambio
y le pasa los argumentos a y b. La función intercambio almacena en x el valor de a y en y el
valor de b. Esto significa que los datos a y b se han duplicado. Esto es, ocurren las siguientes
asignaciones:

x=a
y=b
20 30
a b

20 30
x y

Fundamentos de Programación | Ing. Patricio Vinueza


Los parámetros formales x e y son variables locales a la función intercambio, por lo tanto
sólo son accesibles dentro de la propia función. Esto significa que las variables locales se
crean cuando se ejecuta la función y se destruyen cuando finaliza la ejecución de la función.

* - Paso de parámetros por valor*/


#include <stdio.h>
void intercambio(int, int); /* prototipo de la función*/
int main ()
{
int a= 20, b = 30;
intercambio(a, b); /*a y b son pasados por valor*/
printf ( "a es %d y b es %d\n", a, b); //a es 20 y b es 30
}
20 30
void intercambio(int x, int y)
{
int z = x;
x = y;
y = z;
}

Después de ejecutarse la función intercambio el valor de y ha sido copiado en x y el valor


de x ha sido copiado en y. Lo importante, es que vea que estas operaciones no afectan a los
valores de a y de b.

20 30
a b

20 20 30
z x y

Si lo que se desea es alterar los contenidos de los argumentos especificados en la llamada,


entonces hay que pasar dichos argumentos por referencia. Esto es, a la función se le pasa
la dirección de cada argumento y no su valor, lo que exige que los parámetros formales
correspondientes sean punteros. Para pasar la dirección de un argumento, utilizaremos el
operador &. Por ejemplo:

/* Paso de parámetros por referencia*/


#include <stdio.h>
void intercambio(int *, int *); /* prototipo de la función*/

Fundamentos de Programación | Ing. Patricio Vinueza


void intercambio(int *, int *);
void main ()
{
int a= 20, b = 30;
intercambio(&a, &b); /*ay b son pasados por referencia*/
printf("a es %d y b es %d\n", a, b); //a es 30 y b es 20
}

void intercambio(int *x, int *y)


{
int z = *x; // z = contenido de la dirección X
*x = *y; // contenido de X = contenido de y
*y = z ; //contenido de y = z
}
En el ejemplo expuesto podemos ver que la función intercambio tiene dos parámetros x e
y de tipo puntero a un entero, que reciben las direcciones de a y de b, respectivamente.
Esto quiere decir que al modificar el contenido de las direcciones x e y, indirectamente
estamos modificando los valores a y b. Recordar la definición de puntero y las definiciones
de los operadores de indirección (*) y dirección-de ( & ).

La explicación gráfica del ejemplo que acabamos de ver es la siguiente:

1. La función main define las variables a y b y llama a la función intercambio pasando


las direcciones de dichas variables como argumento. Supongamos que las
direcciones en memoria de estas variables son 16382 y 16384, respectivamente.

16382 16384

20 30
a b

2. Cuando se llama a la función intercambio el valor del primer parámetro actual es


pasado al primer parámetro formal y el valor del segundo parámetro actual es
pasado al segundo parámetro formal. Esto es,
x = &a
y= &b

Los parámetros formales son variables locales a la función que se crean en el


instante en el que ésta es llamada. Según esto,

Fundamentos de Programación | Ing. Patricio Vinueza


16382 16384
x y

3. Ahora x apunta al dato a; esto es, el valor de x especifica el lugar donde se localiza
el dato a dentro de la memoria. Análogamente, diremos que y apunta al dato b.

16382 16384
x y

20 30
a b

Observe que *x hace referencia al mismo dato de memoria que a y que *y hace
referencia al mismo dato de memoria que b.

4. A continuación se ejecutan las sentencias:

int z = *x; // se asigna a la variable z el valor de a


*x = *y; // se asigna a la variable a el valor de b
*y = z ; // se asigna a la variable bel valor de z

20 16382 16384
z x y

30 20
a b

Cuando la función intercambio finaliza, los valores de a y b han sido intercambiados y las
variables x e y, por el hecho de ser locales, son destruidas.

Fundamentos de Programación | Ing. Patricio Vinueza


Por lo tanto, pasar parámetros por referencia a una función es hacer que la función acceda
indirectamente a las variables pasadas. A diferencia de cuando se pasan los parámetros por
valor, no hay duplicidad de datos.

Cuando se trate de funciones de la biblioteca de C, también se le presentarán ambos casos.


Por ejemplo, suponga que desea escribir un programa que lea dos valores a y b y que escriba
la suma de ambos. La solución es la siguiente:

//Sumar dos valores


#include <stdio.h>
void main ()
{
int a= 0, b = 0, s = 0;
printf ( "Valores de a y b: ”);
scanf("%d %d", &a, &b); // leer desde el teclado a y b
s =a+ b;
printf("La suma es %d\n", s);
}

La ejecución de este programa puede ser así:


Valores de a y b: 10 20
La suma es 30

La función scanf lee valores introducidos por el teclado y los asigna a las variables
especificadas; en el ejemplo, a las variables a y b. Ahora, observe que dichas variables son
pasadas por referencia o dirección y no por valor. Por el contrario, la función printf escribe
los valores de las variables o expresiones especificadas; en este caso, observe cómo la
variable s es pasada por valor.

Más adelante estudiaremos con más detalle las funciones printf y scanf.

int a;
int *p; a
p=&a; 85
a=15;
*p=85; p

B4568

B4568

Fundamentos de Programación | Ing. Patricio Vinueza


Fundamentos de Programación | Ing. Patricio Vinueza
Ejemplo
Realice un programa que realice las funciones que a continuación se indican. Todas las
opciones deben ser presentadas al usuario a través de un menú de opciones.
a) Escriba una función en la que se introduzcan 10 enteros y determine cuáles de
estos enteros son pares y cuales son impares.
b) Un número entero es un “número perfecto” si sus factores, incluyendo al 1 (pero
excluyendo en el número mismo), suman igual que el número.
Ejemplo: 6 es un numero perfecto porque 6= 1+2+3. Escriba una función que
regrese los primeros 100 números perfectos. Esta función debe tener una función
anidada que determine al número perfecto.
c) Escriba una función que tome un valor entero de cuatro dígitos y regrese el
número con los dígitos invertidos. Por ejemplo, dado el número 7631, la función
deberá regresar 1367.

Codificación en lenguaje C
#include <stdio.h>
#include <windows.h>
// Prototipos de la funciones del programa
void Pares_Impares();
int Perfecto(int n);
void Numero_Perfecto();
void Inverso();
void Tiempo();

int main()
{
int opcion;
printf("MENU DE OPCIONES \n");
printf("\n 1.- Pares e Impares ");
printf("\n 2.- Numero Perfecto ");
printf("\n 3.- Numero Invertido ");
printf("\n Seleccione una opcion: ");
scanf("%d",&opcion);
switch(opcion)
{
case 1: Pares_Impares(); break;
case 2: Numero_Perfecto(); break;
case 3: Inverso(); break;
default: break;
}
Sleep(5000);

Fundamentos de Programación | Ing. Patricio Vinueza


return 0;
}
//Función que determina los números pares e impares.
void Pares_Impares()
{
int i=0, v, t;
printf("\nNUMEROS PARES E IMPARES \n");
for(i=1;i<=10;i++)
{
printf("\n Introduce el valor %d: ",i);
scanf("%d",&v);
t=v%2;
if (t==0)
printf(" Es un valor par \n");
else
printf(" Es un valor inpar \n");
}
}
//Funcion que determina si un número es perfecto.
int Perfecto(int n)
{
int i, suma,t;
suma=0;
for (i=1;i<n;i++)
{
t=n%i;
if (t==0)
suma=suma+i;
}
if (suma==n)
return 1;
else
return 0;
}
//Funcion que encuentra los numeros perfectos del 1 al 100.
void Numero_Perfecto()
{
int i,t;
printf("\nNUMEROS PERFECTOS \n");
for (i=1;i<=100;i++)
{

Fundamentos de Programación | Ing. Patricio Vinueza


t=Perfecto(i);
if (t==1)
printf(" %d Es un numero perfecto \n",i);
}
}
//Fucion que invierte el orden de los digitos de un numero.
void Inverso()
{
int i,x,t, suma;
printf("\n NUMERO INVERTIDO \n");
printf("\n Ingrese el numero de 4 digitos: ");
scanf("%d",&x);
suma=0;
t=x/1000;
x=x%1000;
suma=suma+t;
t=x/100;
x=x%100;
suma=suma+(t*10);
t=x/10;
x=x%10;
suma=suma+(t*100);
suma=suma+(x*1000);
printf("\n El numero es=%d ", suma);

Fundamentos de Programación | Ing. Patricio Vinueza


Tarea 11 Problemas Propuestos

Elabore en Lenguaje según se le indique de cada uno de los siguientes problemas


y codifiquelos en DEV C++, Enviar archivos fuente en una sola carpeta
comprimido .

Ejercicio 1

Realizar un programa que tenga una función con un puntero a cadena de caracteres
como parámetro, esta función retorna en su nombre la dirección de la cadena convertida
de minúsculas a mayúsculas. El programa debe leer una cadena de caracteres que se
envía a la función para imprimirla en mayúsculas.

Ejercicio 2

Elaborar un programa que lea una línea de entrada en una cadena de caracteres y cuente
cuántos caracteres son dígitos, letras mayúsculas y letras minúsculas; luego imprimir
los resultados. Usar teoría de punteros.

Ejercicio 3

Realizar un programa que introduzca una cadena de caracteres, para modificarla letra a
letra restando 30 del valor numérico que se utiliza para representar cada letra en código
ASCII. Escribir la cadena en forma codificada, luego decodificar la cadena y escribirla.

Ejercicio 4

Construir una función hipotenusa() que calcule la longitud de la hipotenusa de


un triángulo rectángulo, cuando son conocidos los otros dos lados. La función
debe tomar dos argumentos de tipo double y regresar la hipotenusa también
como double. Utilizar esta función en un programa para determinar la longitud
de la hipotenusa de varios triángulos, como se muestra a continuación:

Triángulo Lado Lado 2 Hipotenusa


1
1 3.0 4.0 5.0
2 5.0 12.0 13.0
3 8.0 15.0 17.0

Ejercicio 5

Fundamentos de Programación | Ing. Patricio Vinueza


La función sumar() tiene 3 parámetros: los dos primeros son números enteros
que van a ser sumados y el tercero corresponde al resultado de la suma. En el
programa principal ingresar desde el teclado dos números para sumarlos en
dicha función, y luego imprimir el resultado obtenido.

Ejercicio 6

Escribir un programa que tenga una función que permita intercambiar los valores
de tres variables a, b y c, si es necesario, de tal manera que se cumpla la
relación:
a <= b <= c

El programa debe leer los datos a, b y c para llamar a la función, y escribir los
resultados antes y después de llamar a la función.

Ejercicio 7

Elaborar una función que calcule las raíces de la ecuación cuadrática:


𝑎𝑥 2 + 𝑏𝑥 + 𝑐 = 0

utilizando la fórmula:
−𝑏 ± √𝑏 2 − 4𝑎𝑐
𝑥=
2𝑎

El programa principal lee los coeficientes de la ecuación, a continuación, accede


a la función para obtener la solución deseada, y finalmente escribe los valores
de los coeficientes seguidos de los valores calculados de las raíces x1 y x2, de
acuerdo a los siguientes tipos de raíces obtenidas:

Si b2 - 4ac < 0, las raíces son imaginarias.


Si b2 - 4ac = 0, existe una sola raíz real doble.
Si b2 - 4ac > 0, las raíces son reales y diferentes.

Además, el programa principal debe escribir la ecuación cuadrática con los


valores ingresados, y en caso de que se tenga el coeficiente a igual a 0 presente
un mensaje de error.

Diseño de la Interfaz de usuario

Programa que resuelve las raíces de una ecuación cuadrática

Ingrese el coeficiente (a): 0

Error … ya no representa una ecuación cuadrática


Fundamentos de Programación | Ing. Patricio Vinueza
Programa que resuelve las raíces de una ecuación cuadrática

Ingrese el coeficiente (a): -1


Ingrese el coeficiente (b): 2.3
Ingrese el coeficiente (c): 1

La ecuación ingresada es: -1X² +2.3X+1 = 0

Las raíces son reales y diferentes Las raíces son iguales


X1 = -0.4 X1 = X2 = 1.4
X2 = 2.7

Ejercicio 8 Error … ya no representa una ecuación cuadrática

Elaborar una función que reciba las variables n y r, para imprimir el número de
combinaciones de n objetos tomados de r en r. El número de combinaciones de
n objetos tomados de r en r se calcula con la siguiente fórmula:

𝑛 𝑛!
( )=
𝑟 (𝑛
𝑟! − 𝑟)!

Realizar un programa que lea los números n y r para llamar a la función y luego
escribir los siguientes resultados:

El número de combinaciones de n: ___


objetos tomados de r: _ en r: ___
es: ___

Además, el programa debe tener una función adicional que calcule el factorial
de cualquier número.

Programa que determina las combinaciones de n objetos


tomados de r en r
Ingrese el valor de n: 5
Ingrese el valor de r: 2

El número de combinaciones de 5 objetos


Tomados de 2 en 2
es: 10

Fundamentos de Programación | Ing. Patricio Vinueza


Ejercicio 9

Realizar un programa que lea la fecha actual en el formato año/mes/día, luego


enviar la fecha ingresada a una función para que imprima en palabras la fecha
del día siguiente. Por ejemplo, si se lee:

25/11/2020.

imprimirá:

26 de noviembre de 2020

Validar los datos de ingreso para que se encuentren dentro del rango correcto
de los días, meses y años en otra función. Además, validar en el caso que sea
el año bisiesto esto también en otra función diferente.

Fundamentos de Programación | Ing. Patricio Vinueza

También podría gustarte