[C con Clase] Lenguaje C

Steven R. Davidson vze266ft en verizon.net
Jue Nov 30 00:12:37 CET 2006


Hola Federico,

FEDERICOLUNA en terra.es wrote:
> Hola, es mi primer correo a la lista, y creo que va a ser un poquillo 
> largo, espero no abusar de su buena disposición para ayudar.
> 

Con tal de que te permita expresar tus ideas y plantear tus dudas o 
inquietudes, tómate el tiempo que necesites sin importar la cantidad ni 
tamañop del mensaje. Por supuesto, intenta reducir o eliminar las partes 
superfluas si el mensaje va a ser muy largo.

> He programado durante muchos años (más de 15 años) pasando por BASIC, 
> COBOL, DBASE, CLIPPER, FOXPRO hasta llegar a VISUAL BASIC; hace 6 años 
> que no programo casi nada, sólo tonterías en access; por el trabajo en 
> el que estoy. Como he mencionado el último lenguaje con el que progrmé 
> ha sido Visual basic 6.0 manejando un poco la API de Windows. Ahora me 
> estoy metiendo con C y estoy comenzando desde abajo partiendo por C 
> estandar, para luego pasar a C++. Quiero mencionar que me gusta mucho 
> programar, y quiero aprender C y profundizar en él, para mi no hay 
> mayor satisfacción que ver que tu trabajo y tus esfuerzos dan sus 
> frutos, que tus programas funcionan, que sirven a los demás, y que son 
> utilizados por otros, tanto empresas como personas naturales.
> 

Creo que todos estamos de acuerdo con esta idea, la cual seguimos en 
principio. Algunas personas aprenden lenguajes porque son mandados a 
hacerlo, pero sospecho que en general todos sacamos una satisfacción al 
programar.

> Agradedería que me contestaran a las estas  preguntas:
> 

Muy bien. Veamos las inquietudes que tienes.

> 1.- Según tengo entendido C es un lenguaje de alto nivel muy potente y 
> con funciones de bajo nivel que sirve, entre otras cosas, para el 
> desarrollo de sistemas operativos, Bases de datos, etc. pero no 
> entiendo una cosa: UNIX está desarrollado en C y he visto que C 
> estándar tiene unas cuantas librerías de funciones y un repertorio de 
> instrucciones no muy amplio y la verdad es que mirando un poco por 
> encima no he encontrado nada como para acceder, por ejemplo, al número 
> de serie de la BIOS o a la fecha de la BIOS,  por mencionar algo. Lo 
> mismo, muchas de las librerías de funciones de la API de windows están 
> construidas en C.

Bien. Primeramente, las bibliotecas estándares de ANSI C fueron 
diseñadas especialmente para que fuesen mínimas, comunes, y básicas. Ten 
presente que C puede usarse bajo cualquier sistema o entorno.

Dicho esto, uno puede programar para un sistema que no tiene una BIOS. 
No todos los programas son desarrollados para un ordenador o 
computadora, ni todos los ordenadores tienen por qué tener una BIOS o 
incluso permitir el acceso a una BIOS. Entiendo que todos tenemos un PC 
y estamos acostumbrados alos componentes e ideas que traen los PC's y 
compatibles. Sin embargo, no pienses que todos los sistemas o entornos 
están diseñados como un PC, porque si no tendrás una idea equivocada del 
mundo de la informática. Intel y Microsoft son populares, pero no son 
las únicas compañías existentes ni son líderes en tecnología ni tampoco 
marcan su curso.

Lo que quiero dejar claro es que no todo lo que existe sigue los diseños 
del PC. Por lo tanto, C como un lenguaje de un objetivo general, ofrece 
lo mínimo y supuestamente común de entre todos los entornos y sistemas 
operativos. Lo mismo ocurre con sus bibliotecas estándares de ANSI C. 
Por ejemplo, C y sus bibliotecas ofrecen maneras de acceder y manipular 
la memoria, crear y manejar ficheros, operar aritmética y lógicamente, 
operar con cadenas de caracteres, manipular la fecha y hora del sistema, 
etc..

> 
> ¿Donde se puede encontrar más librerías de C?; ¿se accede a este tipo 
> de información a través de los registros?. ¿se mezcla C con ensamblador 
> para programar funciones de bajo nivel?, ¿dónde está la potencia de C?; 
> ¿de donde se puede obtener una referencia completa de las librerías de 
> funciones existentes para C?.  ¿Existe alguna catalogación por 
> categorías de las librerías de C? Ya sé que por ejemplo Borland tiene 
> sus propias librerías de funciones con muchas de ellas para manejo de 
> dispositivos, puertos, etc, ¿estan desarrolladas estas librerías en C? 
> ¿con que instrucciones? ¿la fuerza de C está en el manejo de punteros?
> 

* Se puede encontrar bibliotecas de C en cualquier lado, tanto si las 
creas tú mismo como si son creadas por otras personas y grupos. Algunas 
bibliotecas son de libre distribución, gratuitas, o incluso comerciales 
y por tanto de pago. Es cuestión de encontrarlas o quizá ya tengas 
algunas con el compilador que uses. Sin embargo, ten presente que estas 
"otras" bibliotecas no son estándares, por lo que no todos los 
compiladores las ofrecerán.

* Supongo que te refieres a acceder a la BIOS. Esto ya depende de la 
BIOS en sí. Puede haber funciones diseñadas para ello. Si no, entonces 
es posible acceder directamente a la memoria de la BIOS para obtener 
información. Por ejemplo,

unsigned char *pBDA = (unsigned char *) 0x00400000;

Ahora podemos acceder a la información a partir de la dirección de 
memoria 0040:000h. Por ejemplo,

unsigned short *pComLpt = (unsigned short *) pBDA;

printf( "COM1: %p\n", pComLpt );
printf( "COM2: %p\n", pComLpt+1 );
printf( "COM3: %p\n", pComLpt+2 );
printf( "COM4: %p\n", pComLpt+3 );
printf( "LPT1: %p\n", pComLpt+4 );
printf( "LPT2: %p\n", pComLpt+5 );
printf( "LPT3: %p\n", pComLpt+4 );

Aparecerá en pantalla algo así:

COM1: 03f8
COM2: 02f8
COM3: 03e8
COM4: 02e8
LPT1: 0378
LPT2: 0278
LPT3: 027c

Sin embargo, ten presente que estás accediendo a memoria delicada al 
funcionamiento del sistema, por lo que un sistema operativo puede 
negarte el acceso con el fin de proteger esta información importante.

Como ejemplo, quiero que veas que sí es posible acceder a la BIOS a 
través de la memoria. Para ejecutar las funciones o servicios de la 
BIOS, entonces necesitarás alguna otra biblioteca con funciones para 
ello o si lo prefieres, puedes escribir tal programa en ensamblador.

* Bueno, casi he contestado a esta pregunta. Sí puedes usar ensamblador 
con C, pero típicamente, se usa ensamblador para crear funciones MUY MUY 
básicas y de bajo nivel para permitir a los programas de C trabajar con 
ellas. En general, es más fácil escribir en C que escribir en 
ensamblador, ya que se trata de un lenguaje de nivel alto.

* La potencia de C está en su diseño de objetivo o propósito general. 
Personalmente, diría que la gran ventaja de C es el manejo de la 
memoria. Existen MUY pocos lenguajes de alto nivel que permitan 
manipular la memoria con tanta facilidad como permite C. También existen 
otras ventajas como es la facilidad de usar funciones escritas por otras 
personas y bajo otros lenguajes. La verdad es que esto realmente es 
cuestión del enlazador, más que del lenguaje.

* Para una referencia, puedes consultar nuestra página. Puedes ir a: 
http://c.conclase.net/librerias/index.php  Por supuesto, Google siempre 
te ayuda.

* Supongo que sí existe una catalogación si miras el agrupamiento de los 
ficheros de cabecera. Por ejemplo, las funciones relacionadas con el 
manejo de cadenas de caracteres se agrupan bajo el fichero de cabecera 
<string.h>. Las funciones que tienen que ver con la hora y la fecha del 
sistema se encuentran en <time.h>. Y así sucesivamente.

* Las funciones de bajo nivel, como las de Borland, están hechas en C y 
en ensamblador. Algunas de las funciones se comunican directamente con 
los servicios de la BIOS, mientras que otras usan funciones del sistema 
operativo MS-DOS, que a su vez usan los servicios de la BIOS.

* Efectivamente, la mayor ventaja de C es el uso de punteros para 
manejar la memoria.

> 2.- Dentro de lo poco que llevo con C he tocado las funciones scanf y 
> printf, en ambas se puede indicar una longitud de campo para el dato 
> que se va a trabajar, pero en printf da igual si se pone o no, porque 
> no le hace ni caso, estoy probando los ejemplos que hago con Turbo C++ 
> 4.5, Dev-C++ y Visual C++ 6.0 y me hace lo mismo, entonces para que hay 
> opciones que no son necesarias o es que la función la copiaron de scanf 
> y se olvidaron de quitarle esta opción?
> 

No. En el caso de 'printf()', la longitud del campo que indicas no es 
forzada, sino que se trata de un mínimo. Por ejemplo,

printf( "%2d", 12345 );

En pantalla, aparecerá:
12345

Esto es porque %2d indica un mínimo de 2 caracteres a imprimir, pero si 
hace falta más caracteres para representar la información, entonces se hace.

Ahora bien, si se trata de un número de coma flotante, entonces sí 
podemos ajustar la cantidad de decimales forzando un redondeo del valor. 
Por ejemplo,

printf( "%.2f", 12.3456f );

Aparecerá en pantalla,
12.35

Sugiero consultar el apéndice C de nuestro curso de C++ acerca de los 
detalles de 'printf()' y otras funciones. Puedes ir directamente a: 
http://c.conclase.net/curso/index.php?cap=902c#lib_printf

No todos los especificadores de 'printf()' son los mismos que bajo 
'scanf()'.

> 3.- Lo mismo en la función scanf si se pone un espacio en blanco antes 
> de la primera cadena de control se supone que evita la asignación de 
> caracteres extraños introducidos anteriormente, pero tampoco me 
> funciona, si pongo 2 instrucciones scanf seguidas una tras otra y en la 
> primera escribo más caractéres de los que se han determinado como 
> longitud de campo, los caracteres restantes se insertan como primeros 
> en la siguiente instrucción scanf, a pesar de que esta última comienza 
> con un espacio en blanco.
> 

Esto tiene que ver con el comportamiento de 'scanf()'. Esta función lee 
y extrae caracteres según algunos criterios. El criterio general es que 
va leyendo caracteres hasta encontrarse con un espacio blanco. Un 
espacio blanco se define como cualquiera de estos caracteres: ' ', '\t', 
'\r', '\n', '\f', y '\v'. Por lo tanto, si se encuentra con cualquiera 
de estos caracteres, 'scanf()' detiene la lectura. Esto implica que los 
caracteres posteriores existen en el búfer (almacenamiento) del teclado. 
Por ejemplo,

char nombre[25];
int edad;

printf( "Nombre completo y edad: " );
scanf( "%s", nombre );
scanf( "%d, &edad );

Digamos que sucede lo siguiente:

Nombre completo y edad: Pepe Ruiz Delgado 18[ENTER]

Esto resultará en la siguiente cadena en el búfer del teclado:

"Pepe Ruiz Delgado 18\n"

Al pasar por el primer 'scanf()', obtenemos lo siguiente:

nombre <- "Pepe\0"

Pero en el búfer del teclado tenemos esto:

"Ruiz Delgado 18\n"

Aquí tenemos un problema, porque la siguiente 'scanf()' intentará leer e 
interpretar un número entero. Por lo tanto, obtendremos esto:

búfer <- "Ruiz Delgado 18\n"

Por lo tanto, 'num' no es asignado ningún valor, y el búfer del teclado 
permanece invariado.

Cada vez que exista una lectura del teclado, tendremos caracteres 
esperando a ser extrídos. Sin embargo, 'scanf()' aplica ciertos 
criterios a modo de "filtros" para decidir si los caracteres deben ser 
extraídos o no. Ten mucho cuidado con esto.

> 4.- Estoy estudiando C estándar de un libro universitario de la 
> colección Schaum; se llama programación en C y es de un tal Byron 
> Gottfried, el libro no está mal. he pensado que después de este libro 
> compraré Estructuras en C de Luis Joyanes,  también de shaum,  
> (entiendo que las estructuras son el punto de partida para la 
> programación orientada a objetos); pero ya me encontré con otro libro 
> del mismo autor y de la misma colección que se llama Algoritmos y 
> Estructurass en C y además,  si no me equivoco, hay otro solamente 
> dedicado a algoritmos; ya no sé que camino seguir para realizar un 
> estudio completo y profundo de C antes de pasar a C++.
> 

Me temo que no conozco estos libros, aunque he visto que muchos siguen a 
Luis Joyanes. Sin embargo, tengo que matizar acerca del término 
"estructuras". Este término es algo ubicuo, y me temo que su definición 
no es la misma en todos los contextos ni situaciones.

Una estructura, en general, no es más que una organización típicamente a 
través de un agrupamiento de datos o miembros que suelen ser 
heterogéneos. Claro está, existen muchas maneras de estructurar u 
organizar los datos para solucionar un problema. Refiriéndonos a esto, 
se suele hablar de "estructuras de datos" que al avanzar entramos en el 
tema de "estructuras dinámicas de datos". Las estructuras más las 
operaciones para manejarlas dan lugar al concepto de TDA: Tipo de Dato 
Abstracto o a veces TAD: Tipo Abstracto de Dato, que proviene de las 
siglas en inglés: TDA.

Bajo C, existe el tipo 'struct' para poder definir y crear nuestro 
propio tipo de dato. Al hablar de "estructuras", a veces existe 
confusión entre 'struct' y el concepto o la teoría de "estructuras". Por 
lo tanto, 'struct' es la típica implementación para representar una 
"estructura".

Sugiero consultar nuestro curso de EDD: Estructuras Dinámicas de Datos, 
para una introducción al tema. Puedes ir a: 
http://c.conclase.net/edd/index.php

Es cierto que con los TDA's podemos entrar fácilmente en la metodología 
de la Programación Orientada a Objetos, y por tanto estamos ante el 
lenguaje C++, como otros existentes.

> Un agradecimiento a todos los colaboradores de la lista que tienen la 
> paciencia de leer nuestros correos y sobre todo de hacernos caso y 
> contestarnos.
> 

De nada; para eso estamos.


Espero haber aclarado las ideas e inquietudes que tenías.

Steven







Más información sobre la lista de distribución Cconclase