Las keywords en cuestión son estas:
extern
static
auto
register
inline
mutable
volatile
No me pregunten sobre 'mutable' y 'volatile' porque no las he usado nunca XD.
El programa trata de mostrar información por pantalla para dejar en claro el lugar de almacenamiento de las variables utilizadas, y su valor de inicialización.
También se deja en claro el uso de estas directivas en funciones.
Otra cosa que quiero aclarar que 'extern' es por defecto, pero yo lo especifiqué explícitamente para esta demostración.
Y también muestro una forma de usar una función que normalmente no se puede usar de un archivo fuente a otro, pero mediante su dirección se puede.
Dejo el código.
main.cpp
Código
// // By 85 // elhacker.net // etalking.com.ar // boyscout_etk@hotmail.com // 2013 // //////////////////////////////////////////////////////////////////////////////////////////////// #include<windows.h> #include<stdio.h> #include "inclusiones.h" //////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////// char* palabra[] = { "Hola", "Mi", "Nombre", "Es", "David", "Y", "El", "Tuyo?" }; char* msgList[] = { "HAHAHA", "HOHOHO", "HUHUHU", 0 }; char* cadenaCortada = "Hola\nMe\nDices\nTu\nNombre\n?\0"; //////////////////////////////////////////////////////////////////////////////////////////////// extern int variable1; extern int variable2 = 0; int variable3 = 0;// Es extern por defecto!, aunque no se especifique extern char cadena1[] = "AAAAAAAAAAAAAAA"; extern char cadena2[] = "AAAAAAAAAAAAAAA"; char cadena3[] = "BBBBBBBBBBBBBBB"; static int x; static int y = 0; //////////////////////////////////////////////////////////////////////////////////////////////// // MAL! (Revisar los conceptos de cada clase de almacenamiento) //auto int varmal1; //auto int varmal2=0; //register int varmal3; //register int varmal4=0; //////////////////////////////////////////////////////////////////////////////////////////////// //Mutable sólo puede ser aplicada a miembros de clases //Sirve para que determinados miembros de un objeto de una estructura o //clase declarado como constante, puedan ser modificados. //////////////////////////////////////////////////////////////////////////////////////////////// //Volatile se usa con objetos que pueden ser modificados desde el exterior del programa, //mediante procesos externos. //Es frecuente encontrar juntos los modificadores volatile y const: //si la variable se modifica por un proceso externo, no tiene mucho sentido que el //programa la modifique. volatile int varilo1; volatile int varilo2 = 0; volatile int ilvolo1 = 10; //int* p_ilvolo1 = &ilvolo1;// MAL! volatile int* p_ilvolo1 = &ilvolo1; //////////////////////////////////////////////////////////////////////////////////////////////// // HACK // El hack consiste en guardar las direcciones de las funciones 'static' y usar // punteros a función en las otras unidades de compilación. // De esa forma, el compilador no lo restringe. DWORD add_Func1_StringCompare = (DWORD)&Func1_StringCompare; DWORD add_Func2_StringLength = (DWORD)&Func2_StringLength; DWORD add_Func3_StripReturn = (DWORD)&Func3_StripReturn; //////////////////////////////////////////////////////////////////////////////////////////////// static int Func1_StringCompare(char* q, char* a) { do { if( *q!=*a ) return -1; if( !*q ) break; q++; a++; } while( *q ); return 0; } //////////////////////////////////////////////////////////////////////////////////////////////// static unsigned int Func2_StringLength(const char* f){ INT i=0; while(*f++) i++; return i; } //////////////////////////////////////////////////////////////////////////////////////////////// static void Func3_StripReturn(char* str) { for(register unsigned int i=0;i<strlen(str);i++) if (str[i]==10 || str[i]==13) { str[i]=' '; } } //////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////// void inline Func4_MostrarCadenas1(){// Inline es sólo para funciones for(int i=0; i<(sizeof(palabra)/sizeof(palabra[0])); ++i) { printf("%d = %s\n", i, palabra[i]); } } //////////////////////////////////////////////////////////////////////////////////////////////// inline void Func5_MostrarMensajes1(){// Inline es sólo para funciones for(char** i = msgList; *i; i++) { MessageBox(0, *i, *i, 0); } } //////////////////////////////////////////////////////////////////////////////////////////////// extern void Func6_getRAM(char* buf){ MEMORYSTATUS Status; ZeroMemory(&Status, sizeof(Status)); Status.dwLength = sizeof(Status); GlobalMemoryStatus(&Status); DWORD dwRAM = (DWORD)(Status.dwTotalPhys/(1024*1024)); wsprintf(buf, "%d MB", dwRAM); } //////////////////////////////////////////////////////////////////////////////////////////////// void Func7_Variables1(){ // Valores de inicio y lugar de almacenamiento de las variables // putchar(10); int var1; int var2 = 0; static int var3; static int var4 = 0; volatile int var5; volatile int var6=0; printf("variable local sin inicializar: %d\n", var1); printf("variable local inicializada: %d\n", var2); printf("variable local static sin asignar: %d\n", var3); printf("variable local static asignada: %d\n", var4); printf("variable local volatile sin asignar: %d\n", var5); printf("variable local volatile asignada: %d\n", var6); // printf("variable global sin asignar: %d\n", variable1); printf("variable global asignada. %d\n", variable2); printf("variable global asignada: %d\n", variable3); printf("variable global static sin asignar: %d\n", x); printf("variable global static asignada: %d\n", y); printf("variable global volatile sin asignar: %d\n", varilo1); printf("variable global volatile asignada: %d\n", varilo2); printf("add variable local sin inicializar: 0x%X\n", &var1); printf("add variable local inicializada: 0x%X\n", &var2); printf("add variable local static sin asignar: 0x%X\n", &var3); printf("add variable local static asignada: 0x%X\n", &var4); printf("add variable local volatile sin asignar: 0x%X\n", &var5); printf("add variable local volatile asignada: 0x%X\n", &var6); // printf("add variable global sin asignar: 0x%X\n", &variable1); printf("add variable global asignada. 0x%X\n", &variable2); printf("add variable global asignada: 0x%X\n", &variable3); printf("add variable global static sin asignar: 0x%X\n", &x); printf("add variable global static asignada: 0x%X\n", &y); printf("add variable global volatile sin asignar: 0x%X\n", &varilo1); printf("add variable global volatile asignada: 0x%X\n", &varilo2); // El problema con la variable1 es que al haber usado 'extern' y no haberle // hecho una asignación de valor. el compilador entiende que se hace referencia // a una variable que está declarada en otra unidad de compilación. } //////////////////////////////////////////////////////////////////////////////////////////////// void Func8_Variables2(){ // Valores de inicio y lugar de almacenamiento de las variables // putchar(10); // Se crean y destruyen automáticamente (no se necesita especificar) auto int varbien1; auto int varbien2=0; // Si es posible, se van a almacenar en algún registro del CPU para tener // un acceso más rápido a ellas. (Tamaño adecuado para entrar en un registro!) register int varbien3; register int varbien4=0; printf("variable local auto sin asignar: %d\n", varbien1); printf("variable local auto asignada: %d\n", varbien2); printf("variable local register sin asignar: %d\n", varbien3); printf("variable local register asignada: %d\n", varbien4); auto int var1 = 85; auto int var2 = var1; printf("var1: %d add: 0x%X\n", var1, &var1); printf("var2: %d add: 0x%X\n", var2, &var2); register int var3 = 85; // Si estubiera en un registro no se obtendría una dirección de memoria! printf("var3: %d add: 0x%X\n", var3, &var3); register int i; // register int i=0; for(i=1; i<=10; i++){ if(i==1) printf("add i: 0x%X\n",&i); printf("%d",i); } putchar(10); } //////////////////////////////////////////////////////////////////////////////////////////////// static void Func9_dummy1(register int* x){ printf("x: %d add: 0x%X\n", *x, &x); } //////////////////////////////////////////////////////////////////////////////////////////////// static void Func10_dummy2(register int y){ printf("y: %d add: 0x%X\n", y, &y); } //////////////////////////////////////////////////////////////////////////////////////////////// static void Func11_dummy3(volatile int z){ printf("z: %d add: 0x%X\n", z, &z); } //////////////////////////////////////////////////////////////////////////////////////////////// // Retorna un INT volatile, sólo se aplica al tipo de retorno. volatile int Func12_dummy4(int arg){ int res = arg; return res; } //////////////////////////////////////////////////////////////////////////////////////////////// void Func13_Argumentos(){ putchar(10); int a = 500; Func9_dummy1(&a); int b = 1000; Func10_dummy2(b); int c = 5000; Func10_dummy2(c); int d = 100000; Func11_dummy3(d); int e = Func12_dummy4(15); printf("%d\n", e); } //////////////////////////////////////////////////////////////////////////////////////////////// int main(){ Func4_MostrarCadenas1(); Func5_MostrarMensajes1(); // Cualquiera de las 2 formas (con o sin extern, es lo mismo) extern void Test1_UnidadDeCompilacion1(); extern void Test2_UnidadDeCompilacion1(); extern void Test3_UnidadDeCompilacion1(); extern void Test1_UnidadDeCompilacion2(); extern void Test2_UnidadDeCompilacion2(); void Test3_UnidadDeCompilacion2(); Test1_UnidadDeCompilacion1(); Test2_UnidadDeCompilacion1(); Test3_UnidadDeCompilacion1(); Test1_UnidadDeCompilacion2(); Test2_UnidadDeCompilacion2(); Test3_UnidadDeCompilacion2(); Func8_Variables2(); Func3_StripReturn(cadenaCortada); printf("%s\n",cadenaCortada); system("pause"); return (0); }
unidad_comp1.cpp
Código
// // By 85 // elhacker.net // etalking.com.ar // boyscout_etk@hotmail.com // 2013 // //////////////////////////////////////////////////////////////////////////////////////////////// #include<windows.h> #include<stdio.h> #include "inclusiones.h" //////////////////////////////////////////////////////////////////////////////////////////////// int (*Ptr_Func1_StringCompare)(char*, char*); //////////////////////////////////////////////////////////////////////////////////////////////// extern void Test1_UnidadDeCompilacion1(){ // Los externs en este caso son locales a esta función. extern void Func6_getRAM(char* buf); char TotalRAM[256] = ""; Func6_getRAM(TotalRAM); putchar(10); printf("Test1_UnidadDeCompilacion1: Total RAM: %s\n", TotalRAM); } //////////////////////////////////////////////////////////////////////////////////////////////// extern void Test2_UnidadDeCompilacion1(){ // Los externs en este caso son locales a esta función. extern DWORD add_Func1_StringCompare; extern char cadena1[]; extern char cadena2[]; extern char cadena3[]; putchar(10); Ptr_Func1_StringCompare = (int(*)(char*, char*))add_Func1_StringCompare; //if(Func1_StringCompare(cadena1, cadena2) == 0)// No se puede! if(Ptr_Func1_StringCompare(cadena1, cadena2) == 0) { printf("Test2_UnidadDeCompilacion1: IGUALES\n"); } // No se puede! porque getRam no es un extern "global" en esta unidad de compilación. //char TotalRAM[256] = ""; //Func6_getRAM(TotalRAM); //printf("Total RAM: %s\n", TotalRAM); } //////////////////////////////////////////////////////////////////////////////////////////////// extern void Test3_UnidadDeCompilacion1(){ // Cualquiera de las 2 formas extern void Func7_Variables1(); void Func7_Variables1(); Func7_Variables1(); }
unidad_comp2.cpp
Código
// // By 85 // elhacker.net // etalking.com.ar // boyscout_etk@hotmail.com // 2013 // //////////////////////////////////////////////////////////////////////////////////////////////// #include<windows.h> #include<stdio.h> #include "inclusiones.h" //////////////////////////////////////////////////////////////////////////////////////////////// // Los externs pueden ser globales para que sirvan en toda esta unidad de compilación unsigned int (*Ptr_Func2_StringLength)(const char*); extern DWORD add_Func2_StringLength; extern char cadena1[]; extern char cadena2[]; extern char cadena3[]; // Cualquiera de las 2 formas extern void Func13_Argumentos(); void Func13_Argumentos(); //////////////////////////////////////////////////////////////////////////////////////////////// extern void Test1_UnidadDeCompilacion2(){ putchar(10); //int len1 = Func2_StringLength(cadena1);// No se puede! Ptr_Func2_StringLength = (unsigned int(*)(const char*))add_Func2_StringLength; int len1 = Ptr_Func2_StringLength(cadena1); printf("Test1_UnidadDeCompilacion2: len1: %d\n", len1); } //////////////////////////////////////////////////////////////////////////////////////////////// extern void Test2_UnidadDeCompilacion2(){ // No se puede! Son 'inline' en otra unidad de compilación //Func4_MostrarCadenas1(); //Func5_MostrarMensajes1(); } //////////////////////////////////////////////////////////////////////////////////////////////// extern void Test3_UnidadDeCompilacion2(){ Func13_Argumentos(); }
inclusiones.h
Código
// // By 85 // elhacker.net // etalking.com.ar // boyscout_etk@hotmail.com // 2013 // //////////////////////////////////////////////////////////////////////////////////////////////// #pragma once //////////////////////////////////////////////////////////////////////////////////////////////// // En el archivo de inclusión no se especifica la clase de almacenamiento. int Func1_StringCompare(char* q, char* a); unsigned int Func2_StringLength(const char* f); void Func3_StripReturn(char* str); void inline Func4_MostrarCadenas1(); inline void Func5_MostrarMensajes1();
CODE
http://www.mediafire.com/?mzuaz5zxtttazut