Posteado por: wozgeass | agosto 23, 2009

Programando en C para linux (segunda parte).


PRINCIPIOS DE C.

En este capitulo de ofrezco una brebe historia del desarrolo del lenguaje C y se consideran tambien sus caracteristicas, el resto del capitulo se ven los aspectos basicos de los programas de C, tales como su estructura, la declaracion de variables, tipos de datos y operadores.

Origenes de C.

El proceso de desarrollo del lenguaje C se origina con la creacion de un lenguaje llamado BCPL, que fue desarrollado por Martin Richards. El BCPL tuvo influencia en un leguaje llamado B, el cual se uso  en 1970  fue inventado por Ken Thompson y permitio el desarollo de C en 1971, el cual lo invento e implemento Dennis Ritchie. Para 1973 el sistema operativo UNIX  casi totalmente escrito en C.

Durante muchos años el estandar para C fue la version 5 del sistema operativo UNIX, documentacion en “The C programming language” escrito por Brian W.  Kernighan and Dennis M. Ritchie en 1978 comunmente referido como K&R.

Posteriormente se hicieron varias implementaciones las cuales mostraban lo siguiente:

  1. Nuevas caracteristicas
  2. Diferencias de maquinas
  3. Diferencias de protocolos
  4. Errores en los compiladores
  5. Malas implementaciones

Esto origino que en el verano de 1983 se estableciera un comité para resolver estas discrepancias, el cual empezó a trabajar en un estandar ANSI C, la cual fue completada en 1988.

Caracteristicas de C.

Algunas caracteristicas mas importantes que define el lenguaje y que han permitido que sea tan popular, como lenguaje de programacion son:

  • Poco codigo (comparado con el ensamblador)
  • Uso extensivo de llamadas a funciones.
  • Comandos breves (poco tecleo).
  • lenguaje estructurado.
  • Programacion de bajo nivel(nivle bits)
  • Implementacion de apuntadores -uso extensivo de apuntadores para la memoria, arreglos, estructuras y funciones.

Las diversas razones por la cual se ha convertido en un lenguaje de uso profesional son:

  • El uso de constructores de alto nivel.
  • El poder de manejar actividades de bajo-nivel.
  • El generar programas eficientes.
  • La posibilidad de poder ser compilado en una variedad de computadoras, con pocos cambios(portabilidad).

Un punto en contra es que tiene una deteccion pobre de errores, lo cual en ocasiones es problematico para los principiantes.

Estructura de un programa en C.

Un programa de C tiene básicamente la siguiente forma:

  • Comandos del preprocesador.
  • Definiciones de tipos.
  • Prototipos de funciones <Declara el tipo de funcion y las variables pasadas a la misma>.
  • Variables.
  • Funciones

Para un programa se debe tener una funcion main().

Una funcion tiene la forma:

<tipo_nombre_de_la_funcion>(parametros){

variables locales.

sentencias de C.

}

Si la definicion del tipo es omitida, C asume que la funcion regresa un tipo entero Nota: Lo anterior puede ser una fuente de problemas en un programa.

A continuacion se muestra un primer programa:

/*Ejemplo programapiñata.c*/   <———- comentario largo

//ejemplo programa piñata            <—————otro tipo de comentario corto

#include<stdio.h>    <———————-archivo cabecera que incluye la libreria de E/S.

main(){    <—–funcion principal

printf(“Este es un programa piñata!!…\n”);

exit(0);

}

Importante:

  • C requiere un punto y coma al final de cada sentencia.
  • printf es una funcion estandar de C, la cual es llamada en la funcion main().
  • \n significa salto de linea. Salida formateada.
  • exit(); es tambien una funcion estándar que hace que el programa termine. En el sentido estricto no es necesario ya que es la ultima línea de main() y de cualquier forma terminará el programa.

En caso de que se hubiera llamado a la funcion printf de la siguiente forma:

printf(“.\1\n..2\n…3\n”);

La salida seria la siguiente:

.1

..2

…3

Variables.

Lenguaje C tiene los siguientes datos simples:

typo                                                 bits                                             Rango

char 8 -124 al 127

unsigned char                                 8                                               0  al  255

signed char                                       8                                             -127  al  127

int                                                     16  o  32                                   2,767 al 32,767

unsigned int                                 16  o 32                                    0   al  65,535

signed int                                       16 o 32                                  igual que el ‘int’

short int                                            16                                        -32,767, al 32,767

unsigned short int                        16                                        0  al  65,635

signed short int                             16                                      igual que ‘short int

long int                                              32                                    -2,147,483,647  al  2,147,483,647

long long int                                    64                                   –((2**63) –1)  al  2**63 –1

signed long int                                32                                   igual que ‘long int

unsigned long int                          32                                   0  al  4,294,967,295

unsigned long long int               32                                       (2**64 ) -1

float                                                   32                                      -3.2 x10 ** +- 38

double                                              64                                      1E-37  al  1E+37 con 10 digitos de precision

long double                                    80                                     1E -37  al  1E+37 con  10 digitos de precision

Los tipos de datos basicos tiene varios modificadores que les preceden. Se usa un modificador para lterar el significado de un tipo base para que encaje con las diversas necesidades o situaciones. Los modificadores son:

signed, unsigned, long y short.

Nota: En C no existen tipo booleanos, se debera utilizar ‘int‘  y 1 para verdadero O cero para falso.

Para declarar una variable en C, se debe seguir el siguiente formato:

<tipo_dato> nombre_variable;

Tipo_dato es un tipo valido de C y nombre_variable puede consistir en uno o mas identificadores separados por una coma. Un identificador debe comenzar con una letra o un guion bajo.

ej.

int numero, numero1;

float real, real1;

char caracter;

Variables globales.

Una variable global se declara fuera de todas las funciones, incluyendo a la funcion ‘main()‘. Una variable global puede ser utilizada en cualquier parte del programa.

ej.

short int numero, numero1, total;

int bool;

char nombre;

main(){

. . .

}

Es tambien posible preinicializar variables globales usando el operador de asignacion ‘=’.

ej.

float suma  = 1.0;

int valor = 3;

char letra = ‘A’;

main(){

. . .

}

Que es lo mismo que:

float suma;

int valor;

char letra;

main(){

suma = 1.0;

valor = 3;

letra = ‘A’;

}

Tambien se permite la asignacion multiple usando el operador ‘=

ej.

a = b = c = d = 3;

… Que es lo mismo, pero mas eficiente que:

a = 3;

b = 3;

c = 3;

d = 3;

La asignacion multiple se puede llevar acabo, si todos los tipo de las variabesl son iguales.

S e puede redefinir los tipos de C usando typedef. Como un ejemplo un simple uso se considera como se crean dos nuevos tipos real y letra.

Estos nuevos tipos pueden ser usados de igual forma como los tipos predefinidos por C.

ej.

typedef   float  real;

typedef   char  letra;

//declarare variables usando el nuevo tipo

real  suma  =  2.2;

letra  sig_letra;

Lectura y escritura de variables.

El lenguaje C usa salida formateada. La funcion printf() tiene un caracter especial para formatear ‘%’ un caracter enseguida define un cierto tipo de formato para una variable.

%c    <———-   caracter.

%s     <———-  cadena de carateres.

%d    <———    enteros.

%f     <———-   flotantes.

%x    <———-  hexadecimal

%o    <———-  octal

%e    <———-  exponencial

%u    <———- entero sin signo

ej.

printf(“%c %d %f”, caracter, entero, flotante);

La sentencia de formato se encierra entre  ”  “, y enseguida las variables. Asegurarse que el orde de formate y los tipos de datos de las variables coincidan.

scanf() es la funcion para entra valores a variables. Su formato es similar a printf().

ej.

scanf(” %c %d %f %s”, &caracter, &entero, &real, cadena);

Obseva que se antepone & a los nombre de las variables, excepto a la cadena de caracteres. En capitulo siguientes hablaremos de apuntadores mas a fondo y explicar mas a fondo el uso de este operador.

Constantes.

Cuando se declara una constante es un poco parecido a declarar una variable, excepto que el valor no pude ser cambiado.

La palabra clave const se usa para declarar una constante, como se muestra a continuacion:

const variable =  1;

int a = 2;

importante:

  • Se puede usar const antes o despues de tipo.
  • Es usual inicializar una constante con un valor, ya que no pude ser cambiada de alguna otra forma.
    La directiva del preprocesador #define es un metodo mas flexible para definir constantes en un programa.
    Frecuentemente se ve la declaracion const en los parametros de la funcion. Lo anterior simplemente indica que la funcion no cambia el valor del parametro.

Operadores Aritmeticos.

Igual que en otros lenguajes de programacion, en C tenemos los operadores aritmeticos mas usuales ( ‘+’ suma, ‘-‘ resta, ‘*’ multiplicacion, ‘/’ divicion y ‘%’ modulo ).

El operador de asignacion es ‘=’:

ej.

valor = 4;

caracter = ‘y’;

Incremento ‘++’ y decremento ‘–‘, lo que es mas eficiente que:

x = x  + 1;

x++;   // mucho mas eficiente y mas lucido que el de arriva.

Los operadores ‘++’  y  ‘–‘  pueden ser prefijos o postfijos. Cuando son prefijos, el valor es calculado antes de que las expresion sea evaluada, y cuando es postfijo es calculado despues que la expresion es evaluada.

ej.

int valor = 1, valor1 = 2, valor3 = 3;

main(){

printf(“[%d]   [%d]   [%d] \n”, valor, valor1, valor3);

printf(“[%d]   [%d]   [%d] \n”, ++valor, ++valor1, ++valor3);  //prefijo se calcula el valor antes de imprimir

printf(“[%d]   [%d]   [%d] \n”, valor–, valor1–, valor3–);   //postfijo se calcula el valor despues de imprimir

printf(“[%d]   [%d]   [%d] \n”, valor, valor1, valor3);

}

El operador ‘%’ (modulo o residuo) solamente trabaja con enteros, aunque existe una funcion para flotantes (fmod()) de la biblioteca matematica.

El operador divicion ‘/’ es para divicion entera y flotante. Por lo tanto hay que tener cuidado. El resultado de x = 3 / 2; es uno, aun si x es declarado como float. La regla es: si ambos argumento en una divicion son enteros, entonces el resultado es entero. Si se desea obtener la divicion con la fraccion, entonces escribirlo como:

x = 3.0 / 2;   ó    x = 3  /  2.0;

y aun mejor:

x = 3.0 / 2.0;

Por otra parte, existen una forma mas corta para expresar calculos en C. Por ejemplo, si se tienen expresiones como:

i = i  + 3;  ó  x = x * (y + 2);

Pero pueden ser escritas para hacer un codigo mas lucido de la siguiente manera:

<exprecion1>   <operador>   =  <exprecion2>

Por lo que tenemos lo siguente:

i  += 3;

y

x  *=  y + 2;

Operadores de Comparacion.

El operador para probar la igualdad es ‘==’, por lo que se debera tener cuidado de no escribir accidentalmente solo ‘=’, ya que:

if ( i = j)   . . .

Es una sentencia legal de C (Sintacticamente hablando aunque el compilador avisa cuando se emplea), la cual copia el valor de “j” en “i”‘, lo cual sera interpretado siempre como verdadero.

Los demas operadores de comparacio son los siguientes:

Diferente          “!=”

menor que       “<“

mayor que       “>”

menor o igual que   “<=”

mayor o igual que  “>=”

Operadores logicos.

Los operadores logicos son usualemente usados con sentencias condicionales o relacionales, los operadores basicos logicos son:

&& ‘Y’ logico,   || ‘O’ logico   y   ‘!’‘ negacion.

Orden de precedencia.

Es necesario ser cuidadosos con el siginificado de expresiones tales como a + b * c,  dependiendo de lo que se desee hacer.

(a + b) * c
ó
a + (b * c)

Todos los operadores tienen una prioridad, los operadores de mayor prioridad son evaluados antes que los que tienen menor prioridad. Los operadores que tienen la misma prioridad son evaluados de izquierda a derecha, por lo que:

a – b – c

es evaluado como:

(a – b) -c

Prioridad de operadores.

alta                       ()  []  ->

!  ~  ++   —  cast *  &  sizeof()

*  /  %

+  –

<<  >>

<   <=  >  >=

==   !=

&

^

|

&&

||

?:

=  +=  -=  *=   /=

De acuerdo con lo anterior tenemos, lo siguiente:

ej.

  • a < 10  &&  2  * b < c

es interpretada como:

(a < 10)  &&  ((2  *  b)  <  c).

wozgeass: push eax, 1

int 80h

EOF!!!

hasta el proximo post…

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

Categorías

A %d blogueros les gusta esto: