Anuncios Google

Datos basicos de C

Tutoriales de Programaciones

En este tutorial aprenderemos unos aspectos básicos, pero no por ello menos importantes, que sin ellos, sería muy dificil completar un programa con éxito. Para entender algunas partes de este tutorial, es mejor saber algo de C, que se puede aprender aquí. Ante todo, no se recomienda tener C como primer lenuaje pues es susceptible coger vicios, malas costumbres y se tiene muy facil el acceso a un bajo nivel de programación.

ATENCION: Este tutorial puede ser editado en cualquier momente para agregar información.

ATENCION2: El tutorial puede contener errores, se agradacería su reporte para que se solucionen.

Buenas y malas costumbres de programación

La programación en C, es sencilla, pero si no se aprende bien se pueden llegar a adoptar malas costumbres de programación. Aquí se presentan algunas tanto malas como buenas con unos ejemplos para ser mejor comprendidas:

Dar valor 0 a las variables externas

En C es recomendable dar a las variables externas un valor inicial de 0, pues al declararlas, aunque se les de automáticamente un valor inicial de 0, es preferible inicializarlas para no dejarlas con los valores bailando.

Uso de return 0;

En las funciones es conveniente, aun cuando no hace falta, poner return 0. Esto se considera una buena costumbre de la programación en C.

Ejemplo:

#include <stdio.h>
 
int main(){
//Declaraciones
   int sumaconreturn();
   void sumasinreturn();
   int a = 10, b = 5;
   int c;
 
   c = a + b;
 
   printf("Resultado de a + b sin funcion: %i\n",c);
 
   printf("Desde main, pero llamando a funcion con return (necesario) es:%i\n", sumaconreturn(a, b));
 
   sumasinreturn(a, b);
 
   getchar();
 
//Observad que hasta a la función main se la coloca un return
   return 0;
//Esta linea también podría haberse escrito 'return;'
}
 
 
//Función que suma dos variables
int sumaconreturn(a, b){
    int c;
    c = a + b;
 
//En esta función si que es necesario, por eso se pone
   return c;
}
 
//Función que suma dos variables muestra ese valor en pantalla
//OJO, aunque se llame sin return, no quiere decir que no lo tenga, sino que no lo necesita
void sumasinreturn(a, b){
   int c;
   c = a + b;
   printf("La suma de a + b en una funcion sin return es el mismo, es: %i", c);
 
//Y aquí va el return que, qunque no haga falta se pone
   return;
//Se podría haber escrito return;
}

Se observa que aun no necesitándose, se pone un return

La salida que generará este programa será:

Resultado de a + b sin funcion: 15
Desde main, pero llamando a funcion con return (necesario) es:15
La suma de a + b en una funcion sin return es el mismo, es: 15

Uso de goto;

ATENCIÓN: goto está considerada como una manera pobre y de mala forma de programación, y si se expone aquí es por el mero hecho de existir, pero no se recomienda su uso en ningún ámbito. Aún así, hay casos en los que no queda elección, pero aunque nos toque uno de estos casos, se deberá comentar en todo momento el porqué del goto y a dónde redirecciona. Esto, claro que no es obligatorio, pero, como ya se dijo, es una mala manera de programación.

El uso de goto es el siguiente:

goto etiqueta;

En donde etiqueta, va el nombre de una etiqueta previamente definida en el programa. Esto es, que el programa buscará la etiqueta a lo largo del programa y nos redireccionará dando el control a la linea donde se localizó etiqueta.

Una etiqueta se define así:

etiqueta:

Ejemplo de uso de goto

//Definición de bibliotecas
#include <stdio.h>
 
int main(){
   int a = 5;
   int c;
 
   printf("Valor de C: ");
   scanf("%i", c);
 
   switch (c + a){
      case 5:
      printf("\nEl valor de c es: 0");
 
      case 7:
      printf("\nEl valor de c es: 2");
 
      default:
      goto etiqueta;
      }
 
...
      etiqueta:
      printf("El valor de c es distinto de 0 y de 2");
 
      getchar();
      return 0;
}

Por supuesto, en este ejemplo ni mucho menos es necesario poner goto, pero es un mero ejemplo.

Normalmente, goto se debería usar en lugares donde se precise de repetir la misma pieza de código repetidas veces, pero la gran parte de estas, es sustituible por una función:

  • Con goto:

//Ejemplo de como sustituir un goto por una función
#include <stdio.h>
 
int main(){
   int a, b;
   float c;
 
   printf("Media de dos números");
 
   repetir:
   printf("\nPor favor, escribe dos números. 0 en uno de los dos para finalizar");
 
   printf("\na = ");
   scanf("%i", a);
 
   printf("\nb = ");
   scanf("%i", b);
 
   if (a == 0 || b == 0) goto repetir;
   else c = (a + b) / 2;
 
   getchar();
   return 0;
}

 

  • Con una función:

//Ejemplo de como sustituir un goto por una función
#include <stdio.h>
 
int main(){
   void hallarmedia();
   int nada;
 
   printf("Media de dos numeros\n");
 
   hallarmedia();
 
   scanf("%i", &nada);
   return 0;
}
 
void hallarmedia(){
 
   int a, b;
   float c;
 
   do {
 
   printf("Por favor, escribe dos numeros distintos de 0. 0 para finalizar:\n");
 
   printf("\na = ");
   scanf("%i", &a);
 
   printf("\nb = ");
   scanf("%i", &b);
 
   c = (a + b)/2;
 
   printf("La media de los dos valores es %.2f\n\n", c);
 
   }while(a != 0 && b != 0)
 
   return;
}

El programa en sí con una función puede ser más largo, pero no más dificil de comprender, por eso es preferible que se haga con una función. Además, una función es facilmente ampliable y modificable, a diferencia de un goto, que habría que adaptar el código prácticamente entero para poder modificarlo.

goto, aunque en C esté visto como una mala costumbre de programación, en lenguajes de bajo nivel se suele utilizar mucho.

Estructuración de un programa en diversas funciones

Estructurar un programa en diversas funciones es una buena costumbre de programación, es decir, en vez de poner todo en main(), donde se tendría que repetir la misma pieza de código 1000 veces, se pone en una función y se la llama cada vez para no tener que volver a escribirlo entero. Esta es otra ventaja del uso de funciones frente a goto.

Declarar funciones

Es una buena práctica de la programación declarar las funciones dentra de las que va a ser accedida aún en momentos que no es necesario. Es decir, si se pone la función al principio del programa, esta no necesitará una declaración, pero es preferible ponerla por ser una buena práctica de la programación. Aquí en este ejemplo se ha modificado el ejemplo anterior para demostrar que aunque no sea necesario se pone. Se han eliminado los tipos de los argumentos de la función para evitar confusiones:

#include <stdio.h>
 
 
//Función
int sumadatos(int a, int b){
   int c;
   c = a + b;
   return c;
}
 
int main(){
//Declaracion de variables
   int a = 10;
   int b = 20;
   int c;
 
//Se observa que se incluye la declaración aún sin ser necesaria.
   int sumadatos();
 
   printf("Suma de dos valores.\n");
 
   c = sumadatos(a, b);
 
   printf("El resultado es: %i", c);
 
   getchar();
   return 0;
}

Tipos en las funciones

Para evitar errores en el momento de la compilación, es preferible poner el tipo de los argumentos en las declaraciones, es decir, entre los paréntesis de la declaración, se pone el tipo de cada argumento:

#include <stdio.h>
 
int main(){
//Declaracion de variables
   int a = 10;
   int b = 20;
   int c;
 
//Ojo, se ponen los tipos de datos separados dentro de los paréntesis 
por comas.
//Corresponden a los argumentos actuales
   int sumadatos(int, int);
 
   printf("Suma de dos valores.\n");
 
   c = sumadatos(a, b);
 
   printf("El resultado es: %i", c);
 
   getchar();
   return 0;
}
 
 
//Función
int sumadatos(int a, int b){
   int c;
   c = a + b;
   return c;
}
 
 
/* Eso se puede escribir:
int sumadatos(int , int )
int a;
int b;
 
{
   int c;
 
   c = a + b;
 
   return c;
}
*/

Se ponen en la declaración de la función los tipos
de los argumentos actuales.

Poner la declaración de tipo en funciones tipo int y char

Las funciones, si se obvia el tipo, automáticamente tendrán un tipo de int, y como en el código ASCII los caracteres equivalen a números enteros, estas también lo tendrán por defecto. Pero aún sin haber sido necesario, en todos los ejemplos expuestos hasta ahora se pone, pues es una buena práctica de la programación.

Break

Break no está considerado como una mala costumbre de programación porque es necesario en las sentencias switch. Pero no está bien visto usarla en otro contexto


 

Código ASCII

El código ASCII es un estandard (American Standard Code for Information Interchange, o lo que es lo mismo, Código estandar Estadounidense para intercambio de información), es un conjunto de códigos que engloba unos valores para escribir mensajes. En la actualidad, está constituido por 127 caracteres, de los cuales son imprimibles sólo los que están entre el 32 al 126, ambos inclusive; el resto de caracteres son sentencias de control utilizadas para complementar textos, la mayoría de ellas obsoletas.

Es un código de 7 bits, pero antiguamente era de 8 bits, pues se empleaba un bit adicional (bit de pariedad). El código ISO 8859-1, es un complemento para el código ASCII, para poder representar algunos idiomas que precisan de caracteres especiales no presentes en el antes mencionado (el español, por ejemplo).


*Tabla del código ASCII

Sentencias de escape

La mayoría de las sentencias de escape van incluidas en el código ASCII, por eso se ponen como un subapartado de este.

Las más importantes y utilizadas son:

  • '\a' Es una alerta, suena como un pitido. Su código ASCII es 007
  • '\b' Equivale a pulsar la tecla retoroceso, o lo que es lo mismo, borra un caracter en pantalla. Número en el código 008
  • '\t' Es un tabulador horizontal, o lo que es lo mismo, hace un espacio en la línea. Número 009
  • '\n' Corresponde a pulsar la tecla intro, es decir, una nueva línea. Se usa aquí en los ejemplos. Código 010
  • '\v' Tabulador vertical. O lo que es lo mismo, un espacio hacia abajo. Código 011
  • '\f' Alimentación de página. No se para que sirve, pero si lo pones en una línea sale un simbolo de esos de género femenino. Número 012
  • '\r' Retorno de carro. Tampoco se para que sirve. código 013
  • '\"' Escribe en pantalla unas comillas. Código ASCII número Número en el código: 034
  • '\'' Escribe en pantalla un apóstrofo. No suele ser necesario en la mayoría de compiladores. Número 039.
  • '\?' Escribe una interrogación. Tampoco suele ser necesario. Código número 063.
  • '\\' Muestra una barra inclinada al revés. Número 092
  • '\0' Nulo. Código 000
  • '\ooo' No es código ASCII. Representa un número octal en el que las oes se sustituyen por 3 cifras.
  • '\xhh' Las h's se sustituyen por cifras, es un número hexadecimal.

 

Tablas de conversión de variables en las funciones printf y scanf

Cuando vayamos a crear un programa en C, lo más probable es que necesitemos usar una de las funciones anteriormente mencionadas. Pero para poder usarlas de un modo correcto, precisamos de saber como usarlas. Aunque a simple vista parezca muy simple, no lo es. Esto no quiere decir que sean complejas, ni mucho menos, pero tiene algunas cosas que puede llegar a rompernos la cabeza por no saber usarlas bien si somo novatos (experiencia propia). Uno de los apartados más importantes, es la introducción y salida de valores de variables. Con esto quiero decir que nos hará falta saber unos conversores con el fin de usarlas bien, si no queremos que a un entero le aparezca un exponente.

Función printf:

En este pseudo-código se muestra una función printf:

printf("Mensaje: %tipo %tipo", nombrevariable1, nombrevariable2);

%tipo sirve para que en su lugar aparezca el valor de la variable situado después del mensaje. Es decir, los valores aparecen respectivamente. La salida de este código, representaría que nombredevariable1 vaya donde el primer %tipo y el segundo con el otro.

Donde tipo, no va el nombre del tipo, es decir, no tendremos que poner %int o nos saltará esa cosa que adoramos tanto, error. Los tipos a escribir se exponen a continuación:

  • i Se utiliza para la salida de valores de variables enteros.
  • u Lo mostrará como un entero con signo.
  • o Entero octal sin el cero inicial.
  • x Para los hexadecimales pero sin mostrar el 0x.
  • c Se usa para caracteres
  • s Se interpretará como una cadena de caracteres.
  • g El dato se muestra como un numero de coma flotante, con o sin exponente según convenga. Cabe destacar que no se mostrarán ni ceros no significativos ni el punto si no es necesario.
  • f Valor de coma flotante sin exponente.
  • e Se muestra como un número de coma flotante con exponente.

Además, C permite otros parámetros en la función printf, que se han de añadir antes de la letra de conversión y despues del porcentaje:

  • número Un número cualquiera indicará que esa es la longitud de campo mínima, es decir, si ponemos un 3, nuestra variable debe tener al menos tres caracteres o cifras. Si es menor, se alinea a la derecha y los faltantes se rellenan con espacios en blanco.
  • .número Un número precedido por un punto, indica longitud de campo máxima, es decir, la cantidad máxima de decimales que se muestran en un valor float. Por ejemplo, si pusiesemos printf("%.4s", palabra); suponiendo que la variable palabra es menor, no varía, pero si es mayor, sólo se mostrarán los 4 primeros caracteres de nuestra variable.
  • h Para datos cortos (entero corto o entero sin signo corto)
  • l Para datos largos (entero largo, entero largo sin signo, o real de doble precisión)
  • L Para datos largos, solo que este hace datos reales de doble precisión largos.
  • - El dato, se pone a la izquierda con espacios a la derecha, ajustándolo al campo anho mínimo a la izquierda.
  • + Con este parámetro, todos los valores numéricos con signo aparecerán precedidos por un signo + o - según se necesite. Sin este, solo los negativos aparecen con signo.
  • 0 Sirve para que aparezcan 0 iniciales en vez de espacios a la derecha cuando la longitud de campo es mayor que el dato. Esto solo funcionará cuando no exista el indicador '-'. (OJO: Algunos compiladores lo detectan como longitud de campo).
  • ' ' (Espacio en blanco) A cada valor positivo le precede un espacio. Si está el indicador '+', se anula.
  • # Se puede usar de dos modos. Con conversión a octal o hexadecimal, hará que aparezca el 0 y el 0x inicial respectivamente, según corresponda. Si se usa con 'f', 'g', o 'e'

Ejemplo de un programa que usa esto:

//Librerías
#include <stdio.h>
 
//Funcion principal
int main(){
 
//Declaración de variables
   int i = 0;
   int a = 16;
   float b = 132.5;
   long double c = 432.634;
   char d = d;
   char cadena[80];
 
//pedir el valor de cadena:
   printf("Introduce una cadena cualquiera:\n");
   scanf("%[^n]", cadena);
 
//Mostrar todo de distintas maneras
   printf("%i %x %o %+u %f %e %g %lf %s %c %10.50s %4lf", a, a, a, a, b, b, b, c, cadena, d, cadena, c);
 
   return 0;
}


 

Conversiones de tipos

Seguro que en el futuro más de una vez necesitaréis usar un conversor de tipo. Los conversores de tipo, así de una manera simple, sirven para convertir el tipo de datos de una variable a otro tipo. Es to es muy sencillo de usar, pero también hay que saber como hacerlo, porque podremos crear un bonito programa que no funciona como queremos por la lógica del código. Esto es, si necesitamos un tipo, pero nosotros queremos convertir nuestra variable que tiene otro tipo, hay que tener cuidado de que tipo se usa, porque podremos perder información (no os asustéis que si perdéis algo es el valor de la variable, no otra cosa), o que el resultado no sea el esperado.

  • Para realizar una conversión de tipo, se debe poner lo siguiente. Cabe destacar que se debe poner en una sentencia de asignación:

(tipo) nombre de variable;

  • Cabe destacar que los conversores de tipo se pueden meter dentro de sentencias:

#include <stdio.h>
 
int main(){
 
   float a;
   int b, c;
 
   printf("Introduce un valor de coma flotante para a:\n");
   scanf("%f",&a);
 
   printf("\nIntroduce un valor entero para b:\n");
   scanf("%i",&b);
 
   c = ((int) a) + b;
 
   printf("\nEl valor de c es: %i\n", c);
 
   system("PAUSE");
   return 0;
}

El resultado de este código, nos mostrará en pantalla un par de preguntas a responder y nos dará la suma de a truncada (es decir, si era 3.2456, se convierte en 3) más b.

  • Aquí se muestra un ejemplo de una sesión con este programa:

Introduce un valor de coma flotante para a:
3.56
Introduce un valor entero para b:
2
El valor actual de c es: 5

Para realizar conversiones de tipo, no es necesario utilizar estos indicadores, es decir, se puede realizar operaciones con varios tipos, pero los resultados podrían ser inesperados, es decir, que podría salir un tipo o una pérdida del valor de la función que no se desea porque no es el objetivo del programa.

 


 

Preferencia de los operadores

Grupo de preferencia                                             Operador/es                                          Asociatividad

Función, array, miembro de estructura,                       () [] · ->                                             De izq a der
puntero a miembro de estructura.

Operadores unarios                                   - ++ -- ! ~ * & sizeof (tipo)                                  De der a izq

Multiplicación aritmética, división y resto                      * / %                                                 De izq a der

Suma y resta aritméticas                                             + -                                                   De izq a der

Operadores de desplazamiento                                   << >>                                               De izq a der

Operadores relacionales                                          < <= >= >                                            De izq a der

Operadores de igualdad                                             == !=                                                De izq a der

'And' a nivel de bits                                                      &                                                   De izq a der

'o exclusiva' a nivel de bits                                            ^                                                   De izq a der

'o' a nivel de bits                                                          |                                                   De izq a der

'y' lógica                                                                     &&                                                  De izq a der

'o' lógica                                                                     ||                                                   De izq a der

Operador condicional                                                    ?:                                                  De der a izq

Operadores de asignación                                   = += -= *= /= %=                                     De der a izq
                                                                       &= ^= |= <<= >>=

Operador coma                                                            ,                                                    De izq a der


 

Detalles varios

Como detalles pequeños, que no merecen tener un apartado por ellos solos:

  • C, por lo menos en consola, no reconoce las tildes y cuando los ponemos sale un carácter muy extraño, por eso es conveniente no usarlos.
  • Se puede llegar a considerar como mala práctica de la programación hacer cualquier cosa que pueda crear confusiones en la lógica del programa (entenderlo). Aún así está permitido programar lo más conciso posible.
4.666665
Tu voto: Ninguno Votos totales: 4.7 (48 votos)

Anuncios Google

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.

Con respecto a eso de las

Con respecto a eso de las buenas y malas costumbres, quisera preguntar: Que tan bueno o malo es ahorrarse el return(0); del final poniendo void main(void){ en lugar del int main(){ ??

Saludos ;)

Imagen de pspgorrister

La pregunta del millón

Lo cierto es que esa pregunta es más difícil de contestar de lo que parece. Concretamente la función main, tiene mucha polémica, y he visto muchos flames en foros de programación sobre ello. Parece ser que el "estándar" correcto es usar int main(). El uso de void main(), aunque ahora extendido, puede dar avisos o errores con algunos compiladores, sobretodo antiguos.

La forma "purista" de hacerlo sería con int y no devolviendo cero, sino EXIT_SUCCESS, que si bien vale 0 es la forma correcta de indicar el valor.

Como consejo, que es lo que hago y no tiene porqué ser lo mejor: si no quieres devolver ningún valor usa el void main().

Si te vas a meter en un proyecto "serio" de miles de lineas de código, que aunque hoy tu función main no devuelva nada, es posible que lo haga en unos meses, mejor hacer las cosas "con las reglas"  y usar int main() return EXIT_SUCCESS.


LuaDiE: Crea en Lua sin teclear código. Compatible HM7, HMv2, LuaPlayer, LuaDEV y PGE.

ok ;)

Menos mal, yo pensaba que estaba agarrando una "mala costumbre" jejejejejeje, gracias por la aclaracion ;)

Saludos :)

mi opinión...

El 'return 0' del main (o EXIT_SUCCESS), es la forma que tiene tu programa de indicarle al sistema u otros programas que la ejecución ha sido correcta. Y en casa de error, indicarlo con un valor distinto de 0 (que uno aprovecha como identificador del error).

Si uno hace un programa que ejecuta a otro, enseguida se da cuenta de lo pràctico que es que el programa le indique si todo ha ido bien, como si de una llamada a otra función se tratara.

 

Puedes comprobar como todas las aplicaciones de linea de comandos (da igual windows, linux...) devuelven correctamente un número. Haz una ejecución correcta y te devolveran un cero, haz una ejecución por ejemplo con paràmetros incorrectos y devolverán un número distinto de 0.

 

Discutir sobre como definir el main es un poco ridículo. Si tu programa es tan simple que siempre va a devolver 0, da igual que uses int o void para el main. Pero en cualquier otro caso, un programa que no devuelva diferentes códigos de error, e incorpore un documento donde se expliquen, es simlemente un programa incompleto.

 

Guiño

Imagen de pspgorrister

Buen tuto, igual que el

Buen tuto, igual que el anteriior, todo muy bien explicado.

Aunque yo discrepo en una cosa, sobre lo que comentas al principio de que todas las funciones tienen que devolver un valor 0. No estoy de acuerdo en absoluto, de hecho, para eso C tiene el void. Ahorra confusiones.

Ejemplo, tenemos en un header imaginario (p.ej numericos.h), la declaración de una función, que imprime el doble de un número. Viendo su sintaxis:

int ImprimeElDoble(int n);

Podemos deducir lo que hace. pero ¿porqué devuelve un int?, ¿se usa para algo?, ¿es un código de error si el número excede el capacidad?. La función no devuelve nada (bueno, devuelve siempre 0), pero sin ver la documentación o el código fuente, no podemos estar seguros de ello. Sin embargo poniendo su declaración como.

void ImprimeElDoble(int n);

Tenemos la seguridad de que no devuelve ningún valor así que no hace falta preocuparse en poder "recoger" ese posible valor. Quizás en una función tan simple sea muy lógico, pero por ejemplo la función qsort del mismo C que podemos encontrar en la stdlib.h:

void qsort(void *base, size_t nmemb, size_t size, int (*compare)(const void *, const void *));

La función de por sí ya es compleja, pero al menos vemos que no devuelve nada, un dato menos a tener  en cuenta. Si devolviera un int, tendríamos que mirar la documentación para ver que devuelve... ¡siempre 0! Indeciso

En lenguajes como Pascal (me encanta ese lenguaje), el tema se soluciona de una forma muy fácil: Si devuelve un valor se le llama función, si no lo devuelve, se le llama procedimiento. Todo bien

Quitando ese matiz, no tengo nada más que objetar, felicitate de nuevo por el gran esfuerzo que estás haciendo introduciendo el C en la comunidad de Coders, a ver si se deciden de una vez a dar "el gran salto" y dejan a Lua.

Un saludo.

 


LuaDiE: Crea en Lua sin teclear código. Compatible HM7, HMv2, LuaPlayer, LuaDEV y PGE.

Imagen de P22

gracias, ya quite el 0

gracias, ya quite el 0

Imagen de Adrian_ac2

Sabes eso ultimo que dices,

Sabes eso ultimo que dices, tienes toda la razón. Seria bueno introducir otros lenguajes a la scene(java, C#, etc) y crear poyectos en conjunto, con fines de desarrollar mas programadores. Por si te interesa armar algo en pos de introducir otros lenguajes o a alguien mas, pues estaria dispuesto a ayudar(aportar)  con lo poco que se y en lo que pueda.

Saludos


 

Imagen de moikop

Muy buen tutorial.

Pedazo de  tuto te has pegado P22, muy bueno y muy bien explicado.

Un saludo.

Imagen de diegoalfredo19

0_o

Zzzz por esto mismo no me gusta la programacion xD, mis totales respetos para los programadores, pero me lo pueden explicar como si tubiera 10 años xD

Imagen de P22

Procura seguir los tutoriales

Procura seguir los tutoriales de aquí, ahí puedes empezar desde 0. Están sin terminar, pero yo los estoy continuando. Saludos

Imagen de RAVMN

yo creo necesitar algo mas

yo creo necesitar algo mas básico :S

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.