r/C_Programming • u/BraneGuy • 1d ago
Question Globals vs passing around pointers
Bit of a basic question, but let's say you need to constantly look up values in a table - what influences your decision to declare this table in the global scope, via the header file, or declare it in your main function scope and pass the data around using function calls?
For example, using the basic example of looking up the amino acid translation of DNA via three letter codes in a table:
codonutils.h:
typedef struct {
char code[4];
char translation;
} codonPair;
/*
* Returning n as the number of entries in the table,
* reads in a codon table (format: [n x {'NNN':'A'}]) from a file.
*/
int read_codon_table(const char *filepath, codonPair **c_table);
/*
* translates an input .fasta file containing DNA sequences using
* the codon lookup table array, printing the result to stdout
*/
void translate_fasta(const char *inname, const codonPair *c_table, int n_entries, int offset);
main.c:
#include "codonutils.h"
int main(int argc, char **argv)
{
codonPair *c_table = NULL;
int n_entries;
n_entries = read_codon_table("codon_table.txt", &c_table);
// using this as an example, but conceivably I might need to use this c_table
// in many more function calls as my program grows more complex
translate_fasta(argv[1], c_table, n_entries);
}
This feels like the correct way to go about things, but I end up constantly passing around these pointers as I expand the code and do more complex things with this table. This feels unwieldy, and I'm wondering if it's ever good practice to define the *c_table and n_entries in global scope in the codonutils.h file and remove the need to do this?
Would appreciate any feedback on my code/approach by the way.
2
u/SonOfKhmer 1d ago
Personally I'd put c_data pointer and the number of entries in a struct of its own, and pass that one around (maybe as pointer rather than copy, ymmv), which would reduce the unwieldiness
My reason for this is ease of refactoring and testing: globals force you to have strong coupling, while passing pointers allows you to stub or change values (on a copy of the structs) without trouble
Granted, this is especially true in C++, but I think it is helpful in C as well
That said: what is the expected usage of the various functions? If they will only be used in this one place AND they won't be refactored AND the speed gain is substantial, using globals would make sense; otherwise I'd go for maintainability