2010-07-08 14 views
6

Estoy usando C (no C++) y no estoy seguro de cómo evitar el uso de variables globales.C - estructura del programa (evitando variables globales, incluye, etc.)

Tengo una comprensión bastante decente de C, su sintaxis y cómo escribir una aplicación básica, pero no estoy seguro de la forma correcta de estructurar el programa.

¿Cómo las aplicaciones realmente grandes evitan el uso de variables globales? Estoy bastante seguro de que siempre tendrá que haber al menos algunos, pero para juegos grandes y otras aplicaciones escritas en C, ¿cuál es la mejor manera de hacerlo?

¿Hay algún buen software de código abierto escrito estrictamente en C que pueda ver? No puedo pensar en ninguno en la cabeza, la mayoría de ellos parecen estar en C++.

Gracias.

Editar

He aquí un ejemplo en el que me gustaría utilizar una variable global en una simple aplicación de la API de enganche, que es sólo una DLL dentro de otro proceso.

Esta aplicación, específicamente, engancha funciones API utilizadas en otra aplicación. Lo hace mediante el uso de WriteProcessMemory para sobrescribir la llamada al original y convertirlo en una llamada a mi DLL.

Sin embargo, cuando un conectando la función API, tengo que volver a escribir el código de la memoria/máquina original.

Por lo tanto, necesito mantener una matriz de bytes simple para ese código de máquina, una para cada función de API enganchada, y hay muchas.

// Global variable to store original assembly code (6 bytes) 
BYTE g_MessageBoxA[6]; 

// Hook the API function 
HookAPIFunction ("user32.dll", "MessageBoxA", MyNewFunction, g_MessageBoxA); 

// Later on, unhook the function 
UnHookAPIFunction ("user32.dll", "MessageBoxA", g_MessageBoxA); 

Lo siento si eso es confuso.

+1

¿Puedes dar un ejemplo específico? ¿Para qué crees que necesitarás una variable global? 99% de las veces, no necesita ser global. –

Respuesta

7

"¿Cómo las aplicaciones realmente grandes evitan el uso de variables globales?"

  1. Use variables estáticas. Si una función necesita recordar algo entre llamadas, use esta versus las variables globales.Ejemplo:

    int running_total (int num) { 
        static int sum = 0; 
        sum    += num; 
        return sum; 
    } 
    
  2. datos Pass a través de parámetros, de modo que se define el valor de un lugar, tal vez main() y se pasa a donde se necesita.

  3. Si todo lo demás falla, siga adelante y use un sistema global pero intente y mitigue los problemas potenciales.

    1. Como mínimo, use las convenciones de nomenclatura para minimizar los posibles conflictos. EG: Gbl_MyApp_DeveloperName. Entonces todas las variables globales comenzarían con la parte Gbl_MyApp_, donde "MyApp" era algo descriptivo de su aplicación.
    2. Intenta agrupar funciones por propósito, de modo que todo lo que necesite un determinado global esté en el mismo archivo (dentro de lo razonable). Entonces, los globales pueden definirse y restringirse a ese archivo (cuidado con la palabra clave extern).
+2

Parece que las variables estáticas ubicadas en archivos diferentes pueden ser mucho más difíciles de seguir que una variable global, con el prefijo de algo, en un solo archivo globals.h. –

+0

Un método que uso es que cada módulo tenga una estructura que se declare en la función main(). Luego se pasa un puntero a esta estructura a la función Init() de los módulos y a cualquier otra función del módulo. Esta estructura contiene todas las variables utilizadas en el módulo. Este es un enfoque y existen ventajas y desventajas para él. Un profesional es que permite que un módulo se pueda usar fácilmente de múltiples maneras. Por ejemplo, un módulo de bucle de control podría usarse para controlar múltiples bucles de control de esta manera. – Seidleroni

1

El software de código abierto mejor recomendado para aprender C en mi universidad fue Linux, por lo que puede obtener ejemplos de su fuente.

2

Existen algunos usos válidos para las variables globales. Las escuelas comenzaron a enseñar que eran malvadas para evitar que los programadores fueran flojos y exagerados al usarlos. Si está seguro de que los datos son realmente necesarios en todo el mundo, úselos. Dado que le preocupa hacer un buen trabajo, no creo que vaya a equivocarse al usar su propio juicio.

0

Las variables globales son casi inevitables. Sin embargo, a menudo se usan en exceso. No son un sustituto para pasar los parámetros adecuados y diseñar las estructuras de datos correctas.

Cada vez que quiera una variable global, piense: ¿y si necesito una más como esta?

+1

¿Tiene un ejemplo concreto de una variable global "inevitable"? – Secure

2

Es fácil, simplemente no los use. crea lo que habría sido ben las variables globales en tu función main(), y luego pasalas desde allí como parámetros a las funciones que las necesitan.

+1

Tenía la intención de ser "arrogante": si es difícil hacerlo, los datos casi con seguridad no deberían ser globales. –

0

pienso lo mismo, variables globales son malas, reduce la legibilidad y aumenta la posibilidad de error y otros problemas.

Explicaré mi ejemplo. Tengo un main() haciendo muy pocas cosas. La mayor parte de la acción proviene de temporizadores e interrupciones externas. Estas son funciones sin parámetros, debido a la plataforma que estoy usando, microcontrolador de 32 bits. No puedo pasar parámetros y, además, estas interrupciones y temporizadores son asincrónicos. La forma más sencilla es una interrupción global, imagine, que llena un búfer, este búfer se analiza dentro de un temporizador, y la información analizada se utiliza, almacena y envía en otros temporizadores. Ok, puedo levantar un indicador de interrupción y procesar en la función principal, pero cuando ejecuto un software crítico de esa manera no es una buena idea.

Este es el único tipo de variable global que no me hace sentir mal ;-)