Documentos de Académico
Documentos de Profesional
Documentos de Cultura
e-mail: {jose.paris,fermin.navarrina}@udc.es
página web: http://caminos.udc.es/gmni
▶ Estructura de un programa
▶ Variable y constantes
▶ Operadores
▶ Sentencias de control
▶ Punteros y vectores
▶ Funciones
1) Lı́neas de programa:
Columna 1 → (c,d,!) Lı́nea de comentario
Columnas 2 a 5 → Etiqueta numérica de lı́nea
Columna 6 → Continuación de lı́nea
Formato fijo
Fortran
Columnas 7 a 72 → Espacio para instrucciones
Columnas 73 a 80 → Espacio para comentarios
No hay formato libre (salvo en versiones modernas de Fortran)
(
El formato es libre.
C
Las instrucciones se gestionan y agrupan mediante “;” y “{ }”
2) Comentarios:
c, d → En la primera columna comenta toda la lı́nea
La letra d se reserva para una opción de compilación
Fortran ! → Comenta la lı́nea desde la posición en la que se encuentra
Es lo habitual hoy en dı́a
cols. 73 a 80 → Son siempre comentarios.
d → Se desactivan comentarios con D. En desuso.
include ’filename’ → Incorpora ficheros de texto externos
Fortran Ej. Ficheros de encabezamiento.
parameter(SIMBOLO=valor) → Remplaza antes de compilar
el texto SIMBOLO por valor.
#define COSA(X) (X + X)
...
(
j = COSA(i);
j = COSA( i++ ); −→ j = (i + + + i + +) ̸=
i++;
4) Programa principal:
!234567
program nombre ! Si se omite se denomina por defecto: main
Fortran
...
end
ó
int main(argc, **argv) /* Devuelve un entero de control
y recibe dos argumentos*/
C1 {
...
}
(1) Esta opción permite incorporar datos al programa que se escriben directamente en la lı́nea de comandos
cuando éste se ejecuta. (Ej. gfortran programa.f -o programa.exe)
5) Grupos de instrucciones:
Las letras mayúsculas y minúsculas son diferentes.
-Salvo en el nombre de funciones (por compatibilidad con otros lenguajes)
-No se recomienda utilizar esta distinción en la práctica
El uso de minúsculas es recomendado (en general).
Se recomienda usar mayúsculas para definir sı́mbolos.
C (Ej. #define PI 3.1415926535)
Se recomienda usar la primera letra mayúscula para nombres de funciones.
(Ej. int Producto(...){...})
El sangrado de las lı́neas se realiza mediante tabuladores.
Es práctica habitual dejar espacios entre las operaciones (Ej. i = j + k;).
Variables:
1) Definición de variable:
Es un nombre simbólico que identifica:
• El nombre de la variable representa la dirección de memoria donde está almacenada.
• Y el espacio de almacenamiento (en función del tipo de variable), esto es: el valor
2) Nombres de variables:
No pueden empezar por un dı́gito numérico (0-9)
Podemos utilizar los caracteres a-z ≡ A-Z, 0-9, ...,$
Se consideran:
-Sólo los 31 primeros caracteres para nombres “internos”
-Sólo los 6 primeros caracteres para nombres “externos”
Fortran . . . dependiendo del compilador y de las opciones de compilación
No se admiten:
-nombres de instrucciones (do, if, etc.)
-nombres de funciones intrı́nsecas (sin, max, int, etc.)
Deben ser mnemónicos
¡OJO!: 0 ̸= O y 1 ̸= ℓ
Se mantienen los mismo criterios que para Fortran
C Hay que tener en cuenta que, en general, a-z̸=A-Z
-Excepto en nombres externos de funciones (por compatibilidad)
2) Nombres de variables:
Nombres reservados:
auto double int struct
break else long switch
case enum register typedef
char extern return union
const float short unsigned
C
continue for signed void
default goto sizeof volatile
do if static while
asm
→ dependiendo de la implementación
fortran
integer*1 (o byte), integer*2, integer*4, integer*8
integer (Lo más habitual) (lógico CPUs 64 bits)
real*4, real*8, real*16
real, double precision, quadruple precision
complex*8, complex*16, complex*32
Fortran
complex,
logical*1, logical*2, logical*4, logical*8
logical −→ Esto es lo más recomendable en la práctica
character *(n) texto → Crea una variable alfanumérica de n caracteres
ForTran
Ej. Fortran
!234567 !234567
implicit real*8(a-h,o-z) implicit real*8(a-h,o-z)
common /exponente/ n
n=2 n=2
x=5. x=5.
call calc(x,n,y) call calc(x,y)
print*,y print*,y
call exit(0) call exit(0)
end end
! !
!------------------------- !-------------------------
! !
subroutine calc(a,i,b) subroutine calc(a,b)
implicit real*8(a-h,o-z) implicit real*8(a-h,o-z)
common /exponente/ i
z=a+1. z=a+1.
b=z**i b=z**i
return return
end end
Ej. Lenguaje C
void main(void)
{
void calc(double, int, double *) /* Prototipo de función */
int n; /* Declaración de variable n */
double x, y; /* Declaración de variables x e y */
n=2;
x=5.;
calc(x,n,&y); /* Llamada a la función calc */
print("%f",y); /* Impresión por pantalla del resultado */
exit(0);
}
void calc(double a, int i, double *pb)
{
double z;
z = a + 1.;
*pb = pow(z,i);
}
▶ A priori, las variables que se modifican en la subrutina se envı́an con & y se reciben con ∗.
4) Constantes:
Fortran
▶ Enteras:
± [nº en base decimal] → cifra entre 0 y 9
▶ Reales:
±123.4 → REAL (Normalmente real*4)
±.1234e+3 → REAL (Normalmente real*4)
±.1234d+3 → DOUBLE PRECISION (Normalmente real*8)
±.1234q+3 → QUADRUPLE PRECISION (Normalmente real*16)
Depende de las opciones de compilación
Se guardan en el tipo correspondiente o por defecto (real*4, real*8, real*16)
4) Constantes:
Fortran
▶ Alfanuméricas:
No son variables como tales. Son Descriptores.
La dirección de memoria del inicio del “string”
Contienen internamente →
La longitud del “string” (número de caracteres)
’hello, world’
→ hello, world
12Hhello,
| {z world }
12 caract.
↑
Formato Hollerith
▶ Lógicas:
.true.
.false.
4) Constantes:
Lenguaje C
4) Constantes:
Lenguaje C
± [número en base decimal] ⇝ cifras (0-9), primera ̸= 0, salvo para el número cero.
± 0[número en base octal] ⇝ cifras (0-7), la primera cifra es un 0.
± 0x[número en hexadecimal] ⇝ cifras (0-9), letras (a-f) ≡ (A-F)
char
short
unsigned
Se guardan en int
signed
long
long long
↓ ↓
según el signo lo mı́nimo necesario
o lo que se indique o lo que se indique
u
constante + → unsigned Ej. 347U
U
Se pueden combinar (Ej. 0xFUL ≡ 15)
l
constante + → long Ej. 2598L
L
NOTA: Las expresiones con constantes enteras se evalúan al compilar (no al ejecutar)
4) Constantes:
Lenguaje C
4) Constantes:
Lenguaje C
4) Constantes:
Lenguaje C
También:
enum boolean {NO,YES} siono, aceptado;
enum {NO,YES} siono, aceptado;
5) Cambios de tipos:
6) Inicialización de variables:
No es posible salvo con la instrucción data
data vble1,vble2,vble3 /valor1, valor2, valor3/
Ej. data m,n,x,y /10,20,2.5,2.5/
data m/10/, n/20/, x,y /2*2.5/
Fortran →
real v(100)
data v/100*0.0/ ! 100 componentes con valor 0.0
Las variables globales se inicializan una vez y al principio
Las variables locales, ¿se inicializan cada vez? → SI
6) Inicialización de variables:
Se pueden inicializar directamente al declararlas:
int i; int i = 3;
int i, j; int i = 3, j = 4;
float pi; float pi = 3.1415926535;
char letra; char letra = ’x’
Una sóla vez las permanentes o globales
Se inicializan:
Cada vez en cada módulo las variables locales
C →
Si se definen como constantes se inicializan y
no pueden ser modificadas a posteriori
const int i = 3;
Se pueden inicializar también vectores al declararlos:
int v[5] = { 1, 2, 3, 4, 5 };
char texto[6] = {’L’, ’u’, ’n’, ’e’, ’s’, ’\0’};
char texto[6] = "Lunes";
Operadores
Fortran C
Incrementales No Sı́
1) Operadores aritméticos:
Fortran:
Unarios: - Cambio de signo. Afecta a una variable.
•
Binarios: +, -, *, / Operaciones elementales. Afectan a 2 variables.
Ej. a * b + c / -d ←→ (a * b) + ( c / (-d))
1) Operadores aritméticos:
C:
Ej. a * b + c / -d ←→ (a * b) + ( c / (-d))
♢ ¡OJO! El compilador puede tomar decisiones. No hay que fiarse.
Si se quiere forzar un resultado es mejor utilizar variables intermedias
a = -1.
Ej. ¿( a + b ) + c = a + ( b + c )? si b = +1.
c = 10−24
1) Operadores aritméticos:
C:
• Abreviaturas:
x op = expresión ←→ x = x op (expresión)
xmod += v[i] * v[i]; ←→
Ej.
v[i] /= xmod;
2) Operadores relacionales:
Fortran:
(
.gt., .ge., .lt., .le. → Mayor, mayor o igual que, menor, menor o igual que.
•
.eq., .ne. → Igual, no igual.
•
Si los escalares son de distintos tipos se promueven al tipo más complejo,
pero no es recomendable.
(
if (i.eq.1)
• Ej.
if (x.gt.5) ! Si x es real*8 → 5 se convierte a real*8
• Tienen menos prioridad que las operaciones aritméticas:
if (x+y.gt.x*y) ←→ if ((x+y).gt.(x*y))
2) Operadores relacionales:
C:
3) Operadores lógicos:
Fortran:
.and., .or. −→ binario
• .not. −→ unario
.eqv., .neqv.
• Tablas de verdad:
a y b son .true.
(a).eqv.(b) es .true. ↔
a y b son .false.
3) Operadores lógicos:
Fortran:
+
.not.
.and. ↑
• Prioridad de operadores →
.or.
↓
.eqv.—.neqv. –
3) Operadores lógicos:
C:
4) Operadores Incrementales:
C:
delante → El incremento es anterior a las operaciones
++, -- −→ por
detrás → El incremento es posterior a las operaciones
y = y - 1;
x = y + z;
¡OJO! x++ = --y + z++; −→
x = x + 1;
z = z + 1;
• Sólo puede aplicarse a variables.
• No puede aplicarse a expresiones.
C:
& bitwise and
|
bitwise or
∧ bitwise exclusive or
<< left shift (Desplaza los bits hacia la izqda. las posiciones indicadas)
>> right shift (Desplaza los bits hacia la dcha. las posiciones indicadas)
∼ complemento a uno (unario)
Ej.: c = n & 0177; → pone a cero todo menos los últimos 7 bits de n,
que no se modifican
↓
(01111111)2
0 “&” 0 → 0
(01111111)2
1→0
→ 01 “&”
& (10101001)2
“&” 0→0
(00101001)2
1 “&” 1 → 1
Ej.: c = n | MASK; → pone a uno todos los bits de n que son uno en MASK
y no cambia el resto
0 “|” 0 → 0
MASK (01111101)2
0 “|” 1 → 1
n | (10101001)2 → 1 “|” 0 → 1
(11111101)2
1 “|” 1 → 1
c = n b MASK; → Uno si los bits de n y MASK son distintos y cero si son iguales
0“b”0→0
MASK (01111101)2
”1→1
→ 01 ““ b
n ∧ (10101001)2 ”0→1
(11010100)2
b
1“b”1→0
x=x*23
x = x << 3; ←→
Si x es entero (y no se viola el rango de la variable)
x = x >> 3; ←→ x=x/23
0177 = (01111111)2
∼0177 = (10000000)2
c = n & (∼ 0177); → Pone a cero los últimos 7 bits de n
(
x = 1
x && y es 1 (TRUE and TRUE = TRUE)
¡ OJO ! ↔ (1)10 = (00000001)2
y = 2 x & y es 0 & (2) = (00000010)
→ (00000000)2 = (0)10
10 2
6) Otros operadores:
Fortran:
• // → Concatenación de strings
Ej. ’Hola ’//’Amigo’
C:
• Ternarios −→ e1 ? e2 : e3
(
Si a > b → z=c
Ej. z = ( a > b ) ? c : d; −→
Si a ≤ b → z=d
7) Recomendaciones finales:
a[i] = i++;
• No fiarse del orden. ¿ ?
a[i] = ++i;
Sentencias de control
if aritmético
if lógico
if — then — else — endif
Fortran
do — enddo
Bucles
do while — enddo
goto (incondicional)
if
if — else
→ Sentencias de ejecución condicionales
if — else —if
switch
for
C while → Bucles
do — while
break
continue → Sentencias de control incondicionales
goto
1.1) IF – ELSE:
if ( exp1 ) {
.........;
.........;
}
if ( exp1 ) else if ( exp2 ) {
.........; .........;
else if ( exp2 ) .........;
.........; }
else if ( exp3 ) else if ( exp3 ) {
.........; .........;
else .........;
Opcional
.........; }
else {
.........;
Opcional
.........;
}
1.3) SWITCH
2.1) WHILE
while ( exp ){
while ( exp ) .......;
sentencia; .......;
}
2.2) FOR
exp1;
while ( exp2 ) {
for ( exp1 ; exp2 ; exp3 )
←→ sentencia;
sentencia;
exp3;
}
▷ ¡ OJO ! La condición se comprueba al principio, antes de cada interación
▷ ¡ OJO ! En este caso, las comas garantizan el orden de evaluación.
(
for ( i = 0 ; i < n ; i++ )
Ej.
for ( i = 0 , j = 0 ; i < n && j < m ; i++, j++ )
2.2) FOR
• Ejemplos:
2.3) DO – WHILE
do do {
sentencia; ó sentencias;
while ( exp ); } while ( exp );
1) CONSIDERACIONES PREVIAS
• Direcciones:
Reserva espacio en memoria para un entero
int i → Guarda la posición de memoria donde se almacena el entero
i contiene el valor que se almacena en ese espacio de memoria
2) PUNTEROS
Aritmética de punteros
Incrementar la posición de memoria: p += 3;
• Decrementar la posición de memoria: p -= 7;
Restar posiciones de memoria: n = p - q;
• Es consistente. (Tiene en cuenta el número de posiciones de memoria del tipo de
variable en cuestión, avanza o retrocede tantos bytes como ocupe cada tipo de variable)
• Todas las demás operaciones están prohibidas (por lógica)
Pasar o enviar variables a funciones
• Uso de punteros
Manejar, dimensionar, ... vectores
2) PUNTEROS
2) PUNTEROS
▶ Ejemplos de aplicación
int main(void)
Sin perder el puntero a
{
↑
int suma ( int , int * );
for ( p = a + n ; p > a ; )
int a[10], sa, n;
{
...
s += *(--p);
sa = suma( n, a );
}
...
↑
}
3) STRINGS
4) VECTORES MULTIDIMENSIONALES
Reserva espacio para N × M enteros tipo int (*)
▶ int m[N][M]; → m es el puntero a un vector de punteros (**)
4) VECTORES MULTIDIMENSIONALES
¡¡ OJO !!
m[i][j] ←→ es un entero:
int n; n = m[i][j];
p ←→ &m[i][0];
(m[i]) ←→ int *p;
p ←→ m[i];
p ←→ &m[i];
m ←→ int (*p)[M];
p ←→ m;
Luego: m ←→ &m[0] m[0] ←→ &m[0][0]
m + 1 ←→ &m[1] m[1] ←→ &m[1][0]
El compilador traduce
m[i][j] ←→ *(m[i] + j) ←→ *(*(m+i) + j)
▶ Las filas se almacenan internamente una a continuación de otra, aunque no necesariamente tiene que
ser ası́.
▶ En los sistemas actuales este STACK es de tamaño reducido y no se recomienda dimensionar arrays
grandes de este modo.
FORTRAN:
Ej.: real *8 v
dimension v(100)
C:
LENGUAJE C
double * pv;
sizeof( tipo ); devuelve el número de bytes que ocupa el tipo de variable indicado
LENGUAJE C
scanf("%d",&n);
scanf("%d",&n);
dyndim(n,v); dyndim(n,&v);
}
}
void dyndim(int n, double v) void dyndim(int n, double ** v)
**
{
{
(*v) = (double*) malloc(n*sizeof(double));
(*v) = (double*) malloc(n*sizeof(double));
} }
1) DESCRIPCION GENERAL
▶ Las funciones son subprogramas encargados de realizar las operaciones de un algoritmo o de parte del
mismo. Convenientemente enlazadas y definidas conforman un programa de ordenador
Funciones del sistema: son funciones propias del compilador que se encuentran en las librerı́as del
sistema. (<stdio.h>, <stdlib.h>, <math.h>)
▶ Definición:
tipo retorno nombre funcion(declaracion parametros, si es necesario)
{
Declaraciones;
Sentencias;
}
▶ Partes:
• tipo retorno: tipo de valor que devuelve la función al finalizar (int, float, int *, ...)
• Nombre función: nombre con el que se identifica la función (OJO: a-z ≡ A-Z)
• declaracion parametros: conjunto de tipos y variables asociadas que recibe la función
1) DESCRIPCION GENERAL
Ej.:
2) DECLARACIÓN DE PARÁMETROS
▶ Los parámetros se envı́an desde la función de origen por valor (En Fortran, por referencia).
▶ La función recibe como parámetros copias de los valores de la función de origen.
▶ Si se modifican en la función no se modifican en la función original.
3) PROTOTIPOS DE FUNCIONES
▶ Los prototipos tienen la misma estructura que las definiciones de función pero
sin nombres de variables. Sólo indican tipos (tanto de retorno como de parámetros)
Ej.:
int power(int , int ); // Los parámetros deben ser dos
variables int y se devuelve otro int
4) LLAMADAS A FUNCIONES
▶ La definición de los parámetros sólo incorpora el nombre de las variables (sin los tipos)
▶ El valor del tipo de retorno se almacena en una variable de tipo adecuado
(salvo en el caso de funciones con tipo de retorno void)
#include <stdio.h>
int power(int , int); // Prototipo de funciones
void main(void)
{
int i, j = 2, k = -3;
for (i = 0; i < 10; ++i )
printf("%d %d %d"\n, i, power(2,i), power(-3,i));
}
int power(int base, int n)
{
int i, p = 1;
for (i = 1; i <= n; ++i)
p = p * base;
return p;
}
5) FUNCIONES Y RECURSIVIDAD
▶ Se dice que una función es recursiva cuando al llamarse a sı́ misma desarrolla
un algoritmo determinado
▶ Las sentencias de la función contienen una llamada a la propia función.
▶ No es en absoluto recomendable para cálculo cientı́fico.
▶ OJO ! El espacio en memoria (stack) necesario para la ejecución aumenta peligrosamente
y no se puede evitar con esta técnica.
int factorial(int n)
{
int i, f;
Función normal for ( i = 1, f = 1; i <= n; i++)
f *= i;
return(f);
}
int Rfactorial(int n)
{
Función recursiva
return( n < 2 ? 1 : n * Rfactorial(n-1));
}
5) FUNCIONES MATEMÁTICAS
1) ACCESO A FICHEROS
▶ Apertura de ficheros:
Se realiza mediante la instrucción fopen como:
fp = fopen ("nombre", "modo apertura")
donde:
fp puntero a un fichero (FILE *)
"nombre" nombre completo del fichero a abrir (y su ruta completa si es necesario)
"r" → Apertura para lectura (“read only”)
"w" → Apertura para escritura (“write”)
"modo"
"a" → Añadir al fichero actual (“append”)
"b" → Lectura o escritura en binario (“binary”)
▶ Cierre de ficheros:
• Se realiza mediante la instrucción fclose como:
fclose( fp );
1) CONSIDERACIONES GENERALES
#include <stdio.h>
Por este motivo es necesario incluir estos ficheros en los programas para
poder utilizar esas funciones
OJO!:
Lee los datos del string de caracteres cuyo puntero se indica y se almacenan en las variables
Escritura
Lectura
Escritura
Lectura
Lee los datos del fichero cuyo puntero (FILE *) se indica y se almacenan en las variables
Escritura
Imprime el caracter almacenado en la variable de tipo int en el fichero del puntero indicado
Devuelve el mismo caracter si no hay errores o bien EOF (End Of File) si hay errores
EOF ← CTRL + Z en entornos Windows
EOF ← CTRL + D en entornos Unix/Linux
Lectura
Lee byte a byte (char a char) los datos del fichero cuyo puntero se indica.
En cada ejecución lee un byte y se coloca para la lectura del siguiente.
El byte leı́do se devuelve como un int
donde:
• argc: contiene el número de argumentos separados por espacios introducidos en el
“command-line”
• argv[]: es un vector (puntero) de strings(punteros) que almacena los textos de los argumentos
introducidos en el “command line”.
argv tiene tantas componentes de tipo string (vector de char’s) como indique argc.
argv[0] es el puntero al string en el que se almacena el propio nombre del programa que se
ejecuta.
argv −→ argv[0] −→ g c c \ 0
argv[1] −→ p r o g r a m a . c \ 0
argv[2] −→ - O 2 \ 0
.. ..
. .
argv[argc-1] −→ p r o g r a m a . e x e \ 0
Consideraciones importantes:
▶ Las componentes de argv son de tipo string (vector de caracteres)
▶ Si desean utilizarse datos del command-line como valores numéricos es necesario utilizar funciones
para transformarlos.
▶ Dado que argv es un vector (puntero) de punteros a strings también se puede indicar como:
int main(int argc, char ** argv)
{
...
}
En este caso,
*(argv+0) ⇐⇒ argv[0]
*(argv+1) ⇐⇒ argv[1]
*(argv+2) ⇐⇒ argv[2]
.. ..
. .
ESTRUCTURAS
Son variables especiales que se componen internamente de otras variables de cualquier tipo
▶ Declaración de estructuras:
ESTRUCTURAS
▶ Miembros de las estructuras:
• Se gestionan como: nombre estructura.nombre variable
coordenadas.x
Ej.:
coordenadas.y
▶ Punteros:
struct COORDENADAS coordenadas;
c = &coordenadas;
UNION
▶ Funcionan igual que las estructuras
▶ Pero sólo existe 1 de sus miembros (el que queramos) en cada caso
▶ La variable union puede almacenar variables de distinto tipo
Ej.:
union {
cosa.i puede almacenar un entero
cosa.x puede almacenar un real
int i;
→
float x;
y ocupan la misma posición de memoria !!!
} cosa
(aunque su tamaño puede ser distinto)
FIELDS
TYPEDEF
typedef int (*pf)();
pf funcion;
→ funcion es un puntero
a una función que devuelve un entero
(
typedef int Length;
▶ Bibliografı́a: