El Administrador de Red debe ser una de esas personas que, durante el trabajo, mientras menos lo vean las cosas estarán mejor. Nada mas imagínese a uno de ellos corriendo como pollo sin cabeza por toda la oficina o aun peor, que de pronto lo llame a Ud. y le diga que apague su PC porque va a restaurar en el servidor todos sus emails que han sido borrados.
Ser Administrador de Red no es fácil, y menos si todos piensan que no hacen nada. La verdad es que si uno de ellos está tranquilo y concentrado es porque algo bueno viene creando en su mente, está optimizando, aprendiendo, ordenando, ellos no están contentos si algo se puede hacer mejor y mas rápido.
Al aprender el lenguaje C las cosas para un Administrador de Red pueden salir mucho mejor y más rápido, deja de estar atado a programas que usa para crear los que realmente quiere y necesita. Conociendo el Lenguaje C las posibilidades de hacer cosas asombrosas son muchas. Es cierto, también pueden salir mal, sobre todo si no prestan atención a los detalles.
Este contenido es un pequeño intento por mejorar el aprendizaje de un Lenguaje que ha hecho posible que tengamos un digno trabajo.
>>Fids
2. Lenguaje C
El Administrador de Red debe ser una de esas personas que, durante el
trabajo, mientras menos lo vean las cosas estarán mejor. Nada mas imagínese a uno
de ellos corriendo como pollo sin cabeza por toda la oficina o aun peor, que de
pronto lo llame a Ud. y le diga que apague su PC porque va a restaurar en el servidor
todos sus emails que han sido borrados.
Ser Administrador de Red no es fácil, y menos si todos piensan que no hacen nada. La
verdad es que si uno de ellos está tranquilo y concentrado es porque algo bueno
viene creando en su mente, está optimizando, aprendiendo, ordenando, ellos no
están contentos si algo se puede hacer mejor y mas rápido.
Al aprender el lenguaje C las cosas para un Administrador de Red pueden salir mucho
mejor y más rápido, deja de estar atado a programas que usa para crear los que
realmente quiere y necesita. Conociendo el Lenguaje C las posibilidades de hacer
cosas asombrosas son muchas. Es cierto, también pueden salir mal, sobre todo si no
prestan atención a los detalles.
Este contenido es un pequeño intento por mejorar el aprendizaje de un Lenguaje que
ha hecho posible que tengamos un digno trabajo.
>>Fids
5. Lenguaje C
Script I – Variables en C
>> Variables
>> Direcciones de Memoria
>> Tamaño
>> Unidad Básica de Almacenamiento
>> Tipos de Datos Básicos en C
>> Tamaño de los tipos de datos básicos en C
>> Limites de los tipos de datos básicos en C
>> Cualificadores de los tipos de datos básicos en C
>> Cualificadores de Tamaño
>> Cualificadores de Valor
>> Resumen de Tipos de Datos
>> Tipos de Datos Especiales
>> Prueba de Concepto - Detrás de las Variables
>> Bonus Track - División de bytes & Protocolo IP
>> Bonus Track – Endianness & Lilliput
>> Tarea para la Casa
>> Anexos
>> Bibliografía
7. Lenguaje C
10 edad
int
0xf0113b1
VARIABLES
Las variables almacenan datos, eso no tiene
ninguna novedad.
El problema es que en C, debemos conocer
QUE ES REALMENTE una variable y DE QUE
ESTA COMPUESTA
Aquí podemos ver una representación de la
línea: int edad = 10;
Pero hay algo que no pusimos en el código…
Y QUE EXISTE REALMENTE
8. Lenguaje C
DIRECCIONES DE MEMORIA
Las variables almacenan datos, PERO nadie
se pregunto en donde se guardan esos
datos…
Por esa razón, tus programas no funcionan
Las variables se guardan en la MEMORIA del
computador, y la única manera de
encontrarlas entre tanta memoria es
mediante su DIRECCION
El 2do problema en el lenguaje C es que las
direcciones de memoria están identificadas
con números HEXADECIMALES…
Y eso no es todo, le antepone las letras 0x
10 edad
int
0xf0113b1
9. Lenguaje C
TAMAÑO
Las variables almacenan datos en
memoria, PERO nadie se pregunto hasta
ahora que tamaño ocupan en memoria
Por esa razón, tus programas son lentos
El tamaño depende de que cosa quiero
guardar en memoria. ¿Un Número?, ¿Una
Letra?, ¿Una Fecha?, ¿Una Imagen?, etc.
Cuando hacemos programas, en realidad no
decimos «que cosa quiero guardar», sino
que «tipo de dato» voy a guardar
Y los tipos de datos tienen ya un tamaño
predefinido en bits
10 edad
int
0xf0113b1
32 bits
10. Lenguaje C
TAMAÑO
Las variables almacenan datos en memoria
que ocupan espacio según su tipo de dato y
son identificadas a través de su dirección de
memoria. PERO se olvidaron de preguntar
cual el tamaño mínimo que podemos
guardar
Por esa razón, tus programas son pesados
En las computadoras, el tamaño mínimo
que puede ser identificado (mediante su
dirección de memoria) es de 8 bits
Y 8 bits forman 1 byte…
10 edad
int
0xf0113b1
32 bits
11. Lenguaje C
UNIDAD BASICA DE ALMACENAMIENTO
0x0361a71
1 byte ¿Y que puedo guardar en 1 miserable byte?
8 bits, y cada bit solo puede representar 2
posibles valores (cero o uno, encendido o
apagado, blanco o negro, sonido o
silencio, etc., etc., etc.)
El mas conocido mundialmente es el de
ceros y unos…
Así nació el uso mundial del Sistema Binario
8 bits
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
12. Lenguaje C
UNIDAD BASICA DE ALMACENAMIENTO
0x0361a71
1 byte ¿Por qué 8 y no 4, 5 ó 6?
Eso lo decidieron nuestros padres, que le
vamos a hacer…
Ellos pensaron que la combinación de 8 bits
da como resultado un buen balance para
interpretar información y ahorrar
complejidad en el seguimiento de las
direcciones de memoria.
Después de todo, 255 valores diferentes no
esta nada mal para representar algo
8 bits
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
13. Lenguaje C
UNIDAD BASICA DE ALMACENAMIENTO
0x0361a71
1 byte ¿255 valores? Y eso de donde salió
No has prestado atención…
Cada bit solo puede tomar uno de 2 posibles
valores. El valor CERO o UNO. Por lo tanto, si
juntamos 8 combinaciones de ceros y
unos, tenemos:
0000 0000 = 0
0000 0001 = 1
0000 0010 = 2
0000 0011 = 3
….
1111 1111 = 255
8 bits
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
14. Lenguaje C
UNIDAD BASICA DE ALMACENAMIENTO
0x0361a71
1 byte ¿Y como se guardan las letras del teclado?
Las letras o caracteres, son en realidad
números que el sistema operativo interpreta.
Por ejemplo, la letra ‘A’ en realidad
corresponde con el número 65. La tecla
ENTER corresponde con el número 13, etc.
Esa correspondencia (número -> carácter)
obedece a estándares internacionales
diseñados hace muchos años.
Un estándar conocido es el formato ASCII
8 bits
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
15. Lenguaje C
UNIDAD BASICA DE ALMACENAMIENTO
0x0361a71
1 byte Si 8 bits me permiten combinar 255 valores
diferentes, y pueden servir para representar
caracteres…
¿Cómo sabemos que el valor 65 hace
referencia al número 65 y no a la letra ‘A’?
…Eso lo sabemos según el TIPO DE DATO que
hemos utilizado
El 3er problema en C es la confusión entre
los tipos de datos y el desconocimiento de
como se almacenan en memoria
8 bits
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
16. Lenguaje C
TIPOS DE DATOS BASICOS EN C
¿Y no que todo era binario…?
Sí, todo lo que guardamos es binario, pero el
Lenguaje C nos permite «CLASIFICAR» lo que
guardamos en binario…
Los tipos de dato nos permiten darle un
«sentido» a la información que guardamos
Técnicamente los tipos de dato se reducen a
números de diferentes tamaños y formas
Es decir, el lenguaje C bailará con números…
char
int
float
double
17. Lenguaje C
TIPOS DE DATOS BASICOS EN C
Caracteres (visibles e invisibles)
Números Enteros
Números de doble precisión
char
int
float
double
Números de simple precisión
18. Lenguaje C
TAMAÑO DE LOS TIPOS DE DATOS BASICOS EN C
char
int
float
double
8 bits
32 bits
32 bits
64 bits
19. Lenguaje C
LIMITES DE TIPOS DE DATOS BASICOS EN C
0 a 255
-2147483648 a 2147483647
Números de doble precisión
char
int
float
double
Números de simple precisión
20. Lenguaje C
CUALIFICADORES DE TIPOS DE DATOS BASICOS EN C
short
long
long long
signed
unsigned
¿Cuali… qué?
Ahora sabemos bien el tamaño que ocupan
los tipos de datos, pero uno llega a
preguntarse:
¿Y si quiero guardar el valor 256, porque
desperdiciar 16 bits que no usare con el int?
¿Y que pasa con los valores negativos?
¿Hay alguna manera de ajustar los tamaños
de los tipos de datos para hacerlos mas
flexibles?
21. Lenguaje C
CUALIFICADORES DE TIPOS DE DATOS BASICOS EN C
¿Qué son los cualificadores?
Son mecanismos en C que permiten
«ajustar» los tamaños o límites de los tipos
de datos básicos, ya sea a modo de
expansión o de reducción en los bits que
ocupan o en su representación numérica
De todos ellos, el cualificador signed es el
cualificador por defecto.
Es decir, todas las variables que se declaren
en un programa en C tendrán el cualificador
signed a menos que se indique lo contrario
short
long
long long
signed
unsigned
24. Lenguaje C
CUALIFICADORES DE VALOR
unsigned char
unsigned int
unsigned short
unsigned
long
8 bits
32 bits
16 bits
64 bits
25. Lenguaje C
RESUMEN DE TIPOS DE DATOS
Tipo de dato signed /
unsigned
Limite signed Limite unsigned
char 8 bits -128 a 127 0 a 255
short [int] 16 bits -32768 a 32767 0 a 65535
int 32 bits -2147483648 a 2147483647 0 a 4294967295
long [int] 64 bits -9223372036854775808 to
9223372036854775807
0 to 18446744073709551615
long long [int] 64 bits -9223372036854775808 to
9223372036854775807
0 a 9223372036854775807
float 32 bits 1.17549e-38 to 3.40282e+38 No existe
double 64 bits 2.22507e-308 to 1.79769e+308 No existe
long double 128 bits 2.22507e-308 to 1.79769e+308 No existe
Nota: Los tipos de datos float, double y long double no usan cualificadores de valor (signed o unsigned)
26. Lenguaje C
RESUMEN DE TIPOS DE DATOS
Nota: Los tipos de datos mostrados son de un servidor Red Hat 6.2 64 bits , es posible que los valores difieran en otros SO
27. Lenguaje C
TIPOS DE DATOS ESPECIALES
¿Qué tienen de especial?
El tipo dato bool solo permite registrar los
valores enteros CERO y UNO
Internamente, el tipo de datos bool ocupa 1
byte (al igual que char), pero no se permite
guardar números diferentes de cero o uno.
Si el valor asignado es diferente de CERO, la
variable de tipo bool tomara el valor UNO.
Este comportamiento nos permite
representar los valores VERDADERO (true,1)
o FALSO (false,0). Para poder usar bool
debemos incluir la librería stdbool.h
bool
void
28. Lenguaje C
TIPOS DE DATOS ESPECIALES
Nótese que usamos el header
stdbool.h para poder usar el
tipo de dato bool
bool
Nota: Una confusión común es no tener claro si 1 es FALSO o VERDADERO. Una forma
sencilla de recordarlo es preguntarse cuanto vale un billete FALSO
29. Lenguaje C
TIPOS DE DATOS ESPECIALES
¿Qué tienen de especial?
El tipo dato void permite guardar cualquier
información para luego ser recuperada según
el tipo de dato que nos interese
El tipo de datos void ocupa 8 bytes debido a
que lo que guarda en realidad son
direcciones de memoria
Para poder usar una variable del tipo
void, deben usarse en forma de punteros
(void *), de lo contrario ocurrirá un error de
compilación
bool
void
31. Lenguaje C
DETRAS DE LAS VARIABLES
edad
int
0x7ffffc127f27
32 bits
8 bits 8 bits 8 bits 8 bits
0000 10100000 00000000 00000000 0000
10
0x7ffffc127f26 0x7ffffc127f25 0x7ffffc127f24
32. Lenguaje C
DETRAS DE LAS VARIABLES
Se puede apreciar que la variable edad
abarca 4 bytes de memoria porque es
de tipo int.
En cambio los valores de tipo char solo
abarcan 1 byte
Ir a siguiente dirección de memoria
Ir a siguiente dirección de memoria
Ir a siguiente dirección de memoria
???
33. Lenguaje C
DETRAS DE LAS VARIABLES – PRUEBA DE CONCEPTO
DEMOSTRADO !
El lenguaje C solamente maneja bits con sus
posiciones de memoria; Es el programador
quien decide como quiere interpretar los
bits valiéndose de los tipos de datos
proporcionados por el lenguaje
Nota: EL orden de los caracteres se debe a que se la arquitectura trabaja con LittleEndian del cual trataremos ma adelante
34. Lenguaje C
DETRAS DE LAS VARIABLES – PRUEBA DE CONCEPTO
DEMOSTRADO !
El tipo de dato void permite ubicarse
en cualquier posición de memoria de
cualquier variable del programa
¿Cuándo USAR VOID?
El uso del tipo de dato void suele utilizarse en programas complejos que requieren alta
velocidad y flexibilidad en la manipulación de datos. Su desventaja es lo peligroso que puede
llegar a ser y lo engorroso en su sintaxis
35. Lenguaje C
DETRAS DE LAS VARIABLES
Las variables son estructuras del lenguaje C que permiten almacenar
información que es accedida mediante una dirección de memoria y que
ocupan un tamaño según sea el tipo de dato y cualificador con las que
fueron declaradas.
El sistema operativo es el responsable de separar el espacio necesario por
cada variable a utilizar
El programador es el responsable de darle la adecuada interpretación a
los datos así como su adecuada manipulación.
Las variables guardan información binaria agrupada en bloques de 8 bits
Dependiendo de la arquitectura del equipo donde se ejecuta un
programa en C, las variables pueden ser almacenadas ya sea en formato
Big Endian o Little Endian
Conociendo el funcionamiento de las variables podremos optimizar
nuestros programas y hackear el sistema!
36. Lenguaje C
BONUS TRACK
0x0361a71
1 byte
8 bits
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
4 bits4 bits
Dividiendo los bytes
Si bien la unidad básica de almacenamiento
es 1 byte, sus 8 bits que lo componen
pueden ser referenciados mediante variables
Por ejemplo, podemos crear 2 variables cada
una de 4 bits o inclusive podemos crear 8
variables de 1 bit cada una
Esto es particularmente útil cuando
diseñamos protocolos de comunicación para
redes de computadoras
37. Lenguaje C
BONUS TRACK
0x0361a71
1 byte
8 bits
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
5 bits3 bits
Dividiendo los bytes
Es importante recordar que si bien podemos
fragmentar los bytes, no podemos reducir su
tamaño de almacenamiento.
Imaginemos que necesitamos guardar los
días de la semana (que son 7) e
ingenuamente pensamos que podremos
optimizar espacio en disco si declaramos una
variable de 3 bits de longitud
La sorpresa será que la variable de 3 bits
declarada sigue teniendo un tamaño de 1
byte
38. Lenguaje C
BONUS TRACK
0x0361a71
1 byte
8 bits
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
5 bits3 bits
Dividiendo los bytes
¿Entonces de que me sirve?
Nos sirve de mucho si queremos ahorrar
espacio al máximo, siempre y cuando
tengamos mas de 1 variable que podamos
incluir en 1 byte
Ejemplo:
Necesitamos 2 variables para almacenar el
día de la semana y el día del mes
39. Lenguaje C
BONUS TRACK
0x0361a71
1 byte
8 bits
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
5 bits3 bits
Dividiendo los bytes
¿Entonces de que me sirve?
El programador común hará algo similar a
esto:
int dia_semana = 7;
int dia_mes = 31;
Estas variables consumen 64 bits (cada int
ocupa 32 bits)
40. Lenguaje C
BONUS TRACK
0x0361a71
1 byte
8 bits
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
5 bits3 bits
Dividiendo los bytes
¿Entonces de que me sirve?
El programador obsesionado con el tamaño
de sus variables hará esto:
struct fecha{
unsigned char dia_semana:3;
unsigned char dia_mes:5;
};
Estas variables juntas consumen solo 8 bits
41. Lenguaje C
BONUS TRACK
0x0361a71
1 byte
8 bits
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
5 bits3 bits
Dividiendo los bytes
Wow !
64 bits vs 8 bits es una diferencia bastante
grande cuando se trata de redes y
comunicaciones.
Es por eso que los protocolos aprovechan
esta característica del lenguaje C para hacer
de las suyas y llevar al limite el envío de
información en pocos bits
42. Lenguaje C
BONUS TRACK
Prueba de
Concepto
Demostrado !
Se puede reducir
significativamente
el tamaño de las
variables
agrupándolas en
estructuras y
dividiendo sus
bytes.
43. Lenguaje C
BONUS TRACK – PROTOCOLO IP
Prueba de Concepto
Demostrado !
Se puede apreciar una implementación
(barata por supuesto) del protocolo IP el
cual aplica el concepto de división de bytes
Un paquete IP normal ocupa 20 bytes
gracias a este mecanismo.
De esta manera se ahorra espacio al enviar
trafico por la red
44. Lenguaje C
BONUS TRACK - ENDIANNESS
edad
int
0x7ffffc127f27
8 bits 8 bits 8 bits 8 bits
0000 10100000 00000000 00000000 0000
10
0x7ffffc127f26 0x7ffffc127f25 0x7ffffc127f24
¿En que orden se almacenan los bits?
Uno de los aspectos mas confusos cuando se aprende el lenguaje C a fondo es la
forma en la que se almacenan físicamente los datos.
45. Lenguaje C
BONUS TRACK - ENDIANNESS
Despedazando el Byte
La forma en la que se numera un byte es de
derecha a izquierda. Esto a veces no es simple de
entenderlo. Pondremos un ejemplo sencillo
Imaginemos que pudiéramos guardar números
decimales dentro de un byte. ¿Cuál sería la
manera correcta de numerar el 765?
¿00000765 o 76500000 ?
A algunos le resulta razonable la 2da forma hasta
que se encuentran con el problema de numerar
7650 o 76500
0x0361a71
7 6 5 4 3 2 1 0
10
MSB LSB
0 0 0 0 1 0 1 0
46. Lenguaje C
BONUS TRACK - ENDIANNESS
Despedazando el Byte
Eso no es todo. Cada byte contiene 2 partes bien
diferenciadas a tener en cuenta.
La posición 0 (cero) que se encuentra mas a la
derecha se le conoce como LSB (Less Significant
Bit) o Bit menos significativo
La posición 7 que se encuentra mas a la
izquierda, se le conoce como MSB (Most
Significant Bit) o Bit Mas significativo
Son utilizados para realizar operaciones con bits 0x0361a71
7 6 5 4 3 2 1 0
10
MSB LSB
0 0 0 0 1 0 1 0
47. Lenguaje C
BONUS TRACK - ENDIANNESS
Prueba de Concepto
Demostrado !
Los datos son almacenados en
bits agrupados en 8 formando
1 byte. Se almacenan siguiendo
la numeración tradicional (de
derecha a izquierda)
48. Lenguaje C
BONUS TRACK - ENDIANNESS
¿Y cuál es el problema?
No hay ningún problema para almacenar 1 byte. El problema viene cuando queremos
almacenar información multibyte (tipos de dato diferentes de char)
32 bits ( 4 bytes)
byte 1byte 2byte 3byte 4
0 0 0 10
32 bits ( 4 bytes)
byte 1byte 2byte 3byte 4
10 0 0 0
Little Endian
Big Endian
¿Por qué es un problema?
Porque todos los equipos con un
formato Little Endian leerán de forma
incorrecta la información proveniente
de los equipos con formato Big Endian y
viceversa
En nuestro ejemplo, el byte 1 es distinto
en ambos formatos. Babilonia otra vez!
49. Lenguaje C
BONUS TRACK - ENDIANNESS
¿De donde provienen los nombres Little Endian y Big Endian?
Los nombres fueron extraídos de la novela «Los viajes de Gulliver» que relata la
disputa en Lilliput por la forma de comer los huevos cocidos. Unos exigían que debía
ser por la parte pequeña (Little Endian) y otros por la parte grande (Big Endian)
32 bits ( 4 bytes)
byte 1byte 2byte 3byte 4
0 0 0 10
32 bits ( 4 bytes)
byte 1byte 2byte 3byte 4
10 0 0 0
Little Endian
Big Endian
El formato Little Endian es el mas
común, sin embargo algunas
arquitecturas trabajan con Big Endian.
Big Endian también es muy utilizado en
la transmisión de datos de red, por lo
tanto la mayoría de protocolos lo
implementa con este formato
50. Lenguaje C
BONUS TRACK - ENDIANNESS
Prueba de Concepto
Demostrado !
El formato Little Endian
empieza su numeración desde
el extremo izquierdo
51. Lenguaje C
TAREA PARA LA CASA
¿No hay cuando acabar con estos tipos?
El lenguaje C no solo tiene tipos de datos
básicos, también tiene otros tipos de datos
que permiten manipular información mas
compleja (como el tiempo)
Incluso, el lenguaje C permite ‘crear’
nuestros propios tipos de datos mediante
estructuras y uniones para representar
entidades mas complejas que un tipo de
dato básico no basta para completarlo
Investiga que otros tipos de datos no básicos
podemos usar en C
clock_t
time_t
wchar_t
wint_t
52. Lenguaje C
TAREA PARA LA CASA
¿No hay cuando acabar con estos tipos?
El lenguaje C es muy popular en el mundo y
ha tenido varios estándares mundiales que
rigen su buen uso y mejoras en el tiempo.
Entre los estándares mas conocidos tenemos
al estándar C99 (1999) y C11 (2011) cuyas
reglas han sido agregadas en los diferentes
compiladores de C.
En estos estándares se recomienda usar
tipos de datos enteros basados en su
tamaño. Investiga cuales son y para que
sirven
int8_t
uint32_t
intptr_t
intmax_t
size_t
… etc
53. Lenguaje C
Anexos
¿Qué necesito para programar en C bajo Linux?
gcc, gdb, vim
¿Cómo compilar un programa C en Linux?
gcc mi-programa.c -g -o mi-programa.exe
¿Cómo depurar un programa C en Linux?
gdb mi-programa.exe
¿Qué necesito para programar en C bajo Windows?
Visual C++ ó Borland C ó C Builder, etc
Nota: La extensión .exe es
solo para referencia
sencilla de que se trata
de un ejecutable, no es
necesario por lo tanto
agregarle dicha extensión
en realidad
Nota: Si se desea
programar con el
estándar C11 se deberá
obtener una copia del
compilador gcc 4.8.1.
54. Lenguaje C
Bibliografia
The C Programming Language, 2nd Edition, B. Kernighan, Dennis Ritchie.
The Art and Science of C, Eric S. Roberts.
Programming in C, 3rd Edition, Stephen G. Kochan
Programación en C, Metodología, algoritmos y estructura de datos. Luis Joyanes
Aguilar
C Programming A Modern Approach. Second Edition. K.K.King
Essential C. Standford CS Education Library. Nick Parlante
55. Lenguaje C
Bibliografia
Bit Numbering (http://en.wikipedia.org/wiki/Bit_numbering)
Endianness (http://en.wikipedia.org/wiki/Endianness)
White Paper: Endianness or Where is Byte 0?. Bertrand Blanc, Bob Maaraoui
Understanding Big and Little Endian Byte Order | Better Explained
(http://betterexplained.com/articles/understanding-big-and-little-endian-byte-order)
Writing endian-independent code in C. Harsha S. Adiga
(http://www.ibm.com/developerworks/aix/library/au-endianc/index.html?ca=drs-)
ISO/IEC 9899:TC2 (C99)