当以不同的名称标记时,函数如何知道要从哪些输入中提取?

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

为什么 int lengthint array[] 的标签与 int TOTALint scores 不同,但它们在 average() 函数中被识别为相同?我以为他们必须被称为相同的东西才能被识别?

#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;
}

在这种情况下,参数称为位置参数。

这意味着,当您定义函数 (float average(int length, int array[]){...}) 时,length 将是第一个参数,而 array 将是第二个。这些名称不是全局名称,仅存在于函数内部。

当您调用函数 (average(TOTAL, scores)) 时,您传递全局(随处可用)变量 TOTAL 作为第一个参数,并为 main 函数传递一个局部变量 scores 作为第二个参数。

lengthTOTAL不一样,它只是在调用函数的时候得到TOTAL的值。 arrayscores.

相同

大多数编程语言中的变量名都有一定的适用“范围”。在 C/C++ 中,范围通常由 {} 字符之间的区域确定,例如其中的函数作用域或循环作用域。

在此具体示例中,TOTAL 是在“全局”范围内定义的。该行之后的任何内容都可以看到并访问该变量。这通常被认为是不好的做法,因为它“污染”了全局范围。想象一下,如果您添加了其他人的代码,而该代码也将 TOTAL 定义为其他内容,会发生什么情况?或者更糟的是,忘记定义它但仍然使用它?没什么好事,我向你保证。

此示例中的所有其他变量都在其自己的“本地”范围内定义。名称 scores 可用 int main(void) { int scores... <HERE> } <but not here>。同样,名称 array 可用 average(int length, int array[]) { <HERE> } <but not here>.

但是如何从一个函数获取数据到另一个函数呢?你调用函数!从 main 开始,当您调用 average(TOTAL, scores) 时,您指的是来自全局范围的名称 TOTAL,以及来自 main 范围的 scores,并传递它们作为函数 average 的“arguments”或“parameters”。函数 average 为这些参数定义了自己的名称,但它们仍将包含来自调用它的地方使用的变量的数据。

这是大多数编程语言必不可少的 属性。没有它,函数调用者将需要确保它们的名称不会与它们调用的函数使用的内部名称冲突,并且 vice-versa。这种机制的相关性可能通过不同的例子更加明显:

// 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(...);
}