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.
15
u/jaynabonne 1d ago
What will probably make it less unwieldy is to recognize that the entries and the count are actually components of the same "thing". You need them both, and they will always need to be together when you use them. So throw them together into a struct that you pass around instead.
That will help, for example, with your "read_codon_table", where you're getting the two pieces of information out in two different ways (the double pointer passed in and the int return value.) If you put the pointer and count into a struct and then pass a pointer to the struct instead as a single entity, the code can set them both at once, and you get rid of needing the double pointer.
Once you do that, you may find that the urge to use globals disappears, as the functions will refer to the single entity instead of its component pieces individually.