[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