Laboratorio de Multimedia e Internet
El alumno adquirirá los conocimientos necesarios para poder crear programas de dificultad básica e intermedia que trabajen sobre una línea de comandos, en el lenguaje de programación C.
C es un lenguaje de programación...
C tiene relativamente pocas: 32 en C89
autobreakcasecharconstcontinuedefaultdodoubleelseenumexternfloatforgotoifintlongregisterreturnshortsignedsizeofstaticstructswitchtypedefunionunsignedvoidvolatilewhileinlinerestrict_Bool_Complex_Imaginaryexternal y static.
GET "libhdr"
LET start() = VALOF
{ writef("Hello world!")
RESULTIS 0
}main()
{
putstr("Hello world!*n");
return(0);
}#include, #define.stdio.h.stdinstdoutstderrLas funciones de la cabecera stdio.h tienen funciones para leer y escribir en archivos.
getsputsscanfprintfprintfLa cadena es un texto, que puede tener dentro especificadores de formato:
%[bandera][ancho][.precisión][tamaño]tipo
scanfLa sintaxis es fundamentalmente la misma que la de printf.
Ejemplo:
"%7d%s %c%lf"
int main(void)
{
int numero;
numero = 2 + 2;
return 0;
}
Para compilar, use el comando:
gcc ejemplo.c -o ejemplo
#include <stdio.h>
void main(void){
printf("Hola Mundo en C");
return 0;
}
Para compilar, use el comando:
gcc ejemplo.c -o ejemplo
Un ejecutable normalmente tiene estas secciones:
.text.data.bss¿Qué es una variable? La respuesta depende de quién pregunte:
[cualificador de tipo] [especificador de almacenamiento] [especificador de tipo];
Especifican la forma en la que se guardará una variable:
externstaticautoregistercharcharsigned charunsigned charshortshort, short int, signed short, signed short intunsigned short, unsigned short intintint, signed, signed intunsigned, unsigned intlonglong, long int, signed long, signed long intunsigned long, unsigned long intlong longlong long, long long int, signed long long, signed long long intunsigned long long, unsigned long long intfloatdoublelong doublefloat _Complexdouble _ComplexLong double _ComplexExisten algunos tipos más elaborados.
void_Boolstructunionenumenumint, agrupadas bajo un identificador.enum identificador { constante [, constante]}enum Foo { A, B=14 }constrestrictvolatilechar: 'x'signed char, unsigned char, short, unsigned shortint:unsigned int: Ulong: Lunsigned long: ULlong long: LLunsigned long long: ULLfloat: Fdouble:long double: L[extern|static] <tipo_valor_retorno> [modificadores] <identificador>(<lista_parámetros>);
[directivas del pre-procesador: includes y defines] [declaración de variables globales] [prototipos de funciones] función main [definiciones de funciones]
extern y static: 1 y 2exp + exp (suma)exp - exp (resta)exp * exp (multiplicación)exp / exp (división)exp % exp (módulo)+ exp (positivo)- exp (negativo)++ var (preincremento)var ++ (postincremento)-- var (predecremento)var -- (postdecremento)var = exp (asignación directa)var op= exp (asignación con operación)(var op= exp) == (var = var op exp).exp == exp (igual que)exp != exp (distinto que)exp > exp (mayor que)exp < exp (menor que)exp >= exp (mayor o igual que)exp <= exp (menor o igual que)exp && exp (conjunción)exp || exp (disyunción)!exp (negación)~exp (negación binaria)exp & exp (conjunción binaria)exp | exp (disyunción binaria)exp ^ exp (disyunción exclusiva binaria)exp << exp (desplazamiento a la izquierda)exp >> exp (desplazamiento a la derecha)exp ? exp : exp (condicional ternario)sizeof(exp) (tamaño en memoria)var[exp] (subíndice)*exp (indirección)&var (dirección)exp->m (dereferencia de estructura)exp.m (referencia de estructura)| Operadores | Asociatividad |
|---|---|
++ (post), --, (), [], ., -> | Izq-a-der |
++ (pre), --, + (unario), -, !, ~, * (indirección), & (dirección), sizeof | Der-a-izq |
*, /, % | Izq-a-der |
+, - | Izq-a-der |
<<, >> | Izq-a-der |
<, <=, >, >= | Izq-a-der |
| Operadores | Asociatividad |
|---|---|
==, != | Izq-a-der |
& | Izq-a-der |
^ | Izq-a-der |
| | Izq-a-der |
&& | Izq-a-der |
|| | Izq-a-der |
?:, =, op= | Der-a-izq |
, | Izq-a-der |
break;continue;return expresión;gotogoto etiqueta;etiqueta:;goto está muy desaconsejado, puesto que va en contra del paradigma estructurado.//, y terminan cuando la línea termina./*, y terminan con */..data o .bss.char o short es convertido a int o unsigned int. En este punto cualquier pareja de operandos será int (con o sin signo), long, long long, double, float o long double.long double, el otro se convertirá a long double.double, el otro se convertirá a double.float, el otro se convertirá a float.unsigned long long, el otro se convertirá a unsigned long long.long long, el otro se convertirá a long long.unsigned long, el otro se convertirá a unsigned long.long, el otro se convertirá a long.unsigned int, el otro se convertirá a unsigned int.int.0 == x equivale a !x.0 != x equivale a x.(tipo)expresión
tipo(expresión)char n;
int a, b, c;
float r, s, t;
c = (int)(r + b);
c = (int)(n + a + r);
Hacer un casting implica que sabemos que el resultado de estas operaciones no es un int, que la variable receptora sí lo es, y que lo que hacemos lo estamos haciendo a propósito.
chars, donde el último elemento del array contiene el valor 0.string.hstrcpystrncpystrcatstrncatstrlenstrcmpstrncmpstrchrstrrchrstrstrmemsetmemcopymemmovememcmpmemchrctype.hlocale.hstdlib.htipo identificador[núm_elemen][[núm_elemen]...];int array[núm_elems];int array[núm_elems] = { contenido }int array[] = { contenido }sizeof, que devolverá el tamaño del array en bytes.struct [identificador] {
[tipo nombre_campo[,nombre_campo,...]];
} [variable_estructura[,variable_estructura,...];struct identificador variable_estructura
[,variable_estructura...];Existen tres formas de asignar valores a un registro.
struct identificador variable;
variable.campo1 = valor1;
variable.campo2 = valor2;
variable.campo3 = valor3;struct identificador variable = { valor1, valor2, valor3 };struct identificador variable = { .campo1=valor1, .campo2=valor2, .campo3=valor3 };sizeof para ello.el todo es más que la suma de sus partes.
struct [identificador] {
unsigned tipo_entero identificador_entero:núm_de_bits;
} [lista_variables];int, puntero a char, puntero a struct Estructura...void.tipo *identificador; Nótese el asterisco.tipo * identificador;
tipo* identificador;int A;
int *pA;
pA = &A;NULL.stdlib.h.*puntero = valor;*puntero no es un objeto en sí, sino una expresión.voidvoid: void *identificador;(tipo *) punterostruct stEstructura* pEstructura;
(*pEstructura).campo;
pEstructura->campo;union [identificador] {
[tipo nombre_variable[,nombre_variable,...]];
} [variable_union[,variable_union,...];
reinterpret_cast<tipo> para lograr este efecto.FILE*.FILEDetermina las operaciones permitidas sobre el archivo.
"r""w""a""r+""w+"FILE * fopen (const char *nombre, const char *tipo);
fopen abre un archivo, pasando el nombre y el tipo de apertura. Devolverá un descriptor válido si pudo abrir el archivo, y NULL si hubo un error.
int fclose (FILE *archivo);
fclose cierra un archivo. Devuelve 0 si se cerró correctamente, EOF si hubo un error.
puts ☞ fputsfputs("cadena") ☞ fputs("cadena", archivo)puts("cadena") ☞ fputs("cadena", stdout).char fgetc(FILE *archivo);
fgetc lee un caracter del archivo. Devuelve el caracter leído, o EOF si hubo un error, o si ya es el final del archivo. Ej.
char *fgets(char *buffer, int tamano, FILE *archivo);
fgets lee caracteres del archivo hasta que el archivo termine, o hasta encontrar un caracter de salto de línea; y los guarda en el buffer especificado. Devuelve el puntero al buffer, o NULL si hubo un error, o si ya es el final del archivo. Ej.
size_t fread(void *puntero, size_t tamano, size_t cantidad, FILE *archivo);
fread lee bloques de datos de un tipo específico. La función recibe un puntero al buffer, el tamaño de un bloque, y la cantidad de bloques a leer del archivo. Devuelve el número de registros leídos.
int fscanf(FILE *fichero, const char *formato, argumento, ...);
fscanf lee una cadena con formato. Devuelve el número de elementos leídos, o EOF si la lectura falló o si ya es el final del archivo. Ej.
int fputc(int caracter, FILE *archivo);
fputc escribe un caracter en el archivo. Devuelve el caracter escrito, o EOF si falló. Ej.
int fputs(const char *buffer, FILE *archivo);
fputs escribe una cadena completa en el fichero, sin contar el caracter nulo. Devuelve el número de caracteres escritos, o EOF si falló. Ej.
size_t fwrite(void *puntero, size_t tamano, size_t cantidad, FILE *archivo);
fwrite escribe bloques de datos de un tipo específico. La función recibe un puntero al buffer de datos, el tamaño de un bloque, y la cantidad de bloques a escribir del archivo. Devuelve el número de registros escritos. Ej.
int fprintf(FILE *archivo, const char *formato, argumento, ...);
fprintf escribe una cadena con formato. Devuelve el número de caracteres escritos, o un número negativo si falló. Ej.
fread y fwrite no lo hacen.feof devuelve 0 mientras no se alcance el final del archivo.ferror devuelve 0 mientras no haya ocurrido un error.clearerr elimina la marca de error en el descriptor de archivo.rewind regresa el cursor de un descriptor al inicio del archivo.Se refiere a si los tipos de datos se comprueban durante la compilación o ejecución del programa:
int main(void){
int a = 5;
char* b = "6";
return a + b;
}let a = 5;
let b = "6";
console.log(a+b);Se refiere a la severidad con la que se hacen cumplir las reglas de tipado del lenguaje.
int main(void){
int a = 5;
float b = 6.0;
return a + b;
}procedure Main is
A : Integer := Integer'Last;
B : Integer;
begin
B := A + 5;
end Main;Se refiere a si el tipo de una variable se indica en código (explícito), o es inferido a partir del valor asignado (implícito).
int main(void){
char s[] = "Test String";
float x = 0.0f;
int y = 0;
return 0;
}a = 4
b = 4.0
c = '4'
type(a)
type(b)
type(c)Se refiere a la forma de determinar si dos variables tienen el mismo tipo.