Home > Software engineering >  How does a function know what inputs to draw from when labeled under different names?
How does a function know what inputs to draw from when labeled under different names?

Time:02-11

How can int length and int array[] be labeled differently than int TOTAL and int scores, yet they are recognized as being the same in the average() function? I assumed they had to be called the same thing in order to be recognized?

#include <cs50.h>
#include <stdio.h>

float average();

const int TOTAL = 3;

int main(void)
{
    int scores[TOTAL];
    for (int i = 0; i < TOTAL; i  )
        {
        scores[i] = get_int("Score: ");
        }

    printf("Average: %f\n", average(TOTAL, scores));

}

//int array [] same as saying int scores [] ?
//int 'length' same as saying 'TOTAL' ?
float average(int length, int array[])
{
    int sum = 0;
    for (int i = 0; i < length; i  )
    {
        sum  = array[i];
    }
    return sum / (float) length;
}

CodePudding user response:

Variable names in most programming languages have a certain "scope" that they apply to. In C/C , scopes are often determined by regions between a { and } character, e.g. a function scope or a loop scope within it.

In this specific example, TOTAL is defined in the "global" scope. Anything after that line can see and access that variable. This is generally considered bad practice, because it "pollutes" the global scope. Imagine, what would happen if you added someone else's code that also defined TOTAL to be something else? Or worse, forgot to define it but used it anyway? Nothing good, I promise you.

All other variables in this example are defined in their own "local" scope. The name scores is usable int main(void) { int scores... <HERE> } <but not here>. Likewise, the name array is usable average(int length, int array[]) { <HERE> } <but not here>.

But how do you get data from one function to another? You call the function! From main, when you call average(TOTAL, scores), you are referring to the name TOTAL from the global scope, and scores from main's scope, and passing them as "arguments" or "parameters" to the function average. The function average defines its own names for those arguments, but they will still contain the data from the variables used where it is called.

This is an essential property of most programming languages. Without it, function callers would need to make sure their names don't conflict with the internal ones used by the functions they call, and vice-versa. The relevance of this mechanism might be more obvious with a different example:

// convert a temperature in celcius to farenheit
float c2f(float celcius) {
  return 1.8f * celcius   32.0f;
}

// print the computer temperature sensor values in farenheit
void print_computer_temperatures(temperatures_t temps) {
  float gpu_temp = c2f(temps.gpu);
  float cpu_temp = c2f(temps.cpu);
  float chipset_temp = c2f(sys()->GetTemp(CHIPSET));
  float chassis_temp_c = -1;
  CoolerMasterQueryChassisTemp(&chassis_temp_c);
  float chassis_temp = c2f(chassis_temp_c);
  printf(...);
}

CodePudding user response:

In this case, the arguments are called positional.

This means, that when you define a function (float average(int length, int array[]){...}), length will be the firs argument and array will be the second. These names are not global and exist only inside the function.

When you call the function (average(TOTAL, scores)), you pass global (availiable from everywhere) variable TOTAL as the first argument, and a local for main function variable scores as the second argument.

length is not the same as TOTAL, it just gets the value of TOTAL when the function is called. Same for array and scores.

  • Related