"C" 函数内的数据操作
Data manipulation inside a function in "C"
这里有一些我不明白的地方。也许有人可以阐明它。
我知道数据操作的标准方法是传递对函数的引用并更改函数中的数据。像这样:
#include <stdio.h>
#include <stdlib.h>
void function2( float *param) {
printf("I've received value %f\n", *param);
(*param)++;
}
int main(void) {
float variable = 111;
function2(&variable);
printf("variable %f\n", variable);
return 0;
}
当用 (&variable) 调用 function2 时,我希望函数可以更改数据。
到目前为止没有问题。
但为什么这也有效?
#include <stdio.h>
#include <stdlib.h>
void function2( float ¶m) {
printf("I've received value %f\n", param);
(param)++;
}
int main(void) {
float variable = 111;
function2(variable);
printf("variable %f\n", variable);
return 0;
}
据我了解,当调用 function2(variable) 时,会将“variable”值的副本传递给该函数。但是尽管如此,“变量”的值在函数调用后发生了变化。
当阅读这样的代码时,无论函数内部发生什么,我都不会期望“变量”的数据发生变化。
变体 1 需要一个 指针 作为参数。因此,您需要显式传入 &variable
.
变体 2 需要一个 reference 作为参数。它们 有点 就像一个指针,因为它们仍然指向内存中的原始位置,但也有点不同,因为它们在类型方面不仅仅是一个地址在记忆中。就像,如果我没记错的话,你不能用引用做时髦的指针运算。
如您所见,如果函数需要引用作为参数,编译器将知道该怎么做,而无需您显式创建引用。
此外,如您所见,如果有人调用您的函数但没想到它会更改原始数据,这可能会带来令人讨厌的意外。这就是为什么在干净的代码中你不会引入意想不到的副作用;如果一个函数弄乱了输入,那应该是它唯一做的事情,而且应该非常明确。
要最终获得不改变原始版本的变体,
void function2( float param)
在函数声明中。没有 *
也没有 &
。在这种情况下,该函数没有获得指针或引用,而只是一个浮点值,它现在将是输入参数的 copy,因此不会更改您的变量。
这个参数声明
void function2( float ¶m) {
不正确。在 C 中没有引用。这样的函数声明将在存在引用的 C++ 中有效。
在 C++ 中调用函数时
function2(variable);
没有创建变量的副本。函数引用main中声明的原始变量。
您发布的代码不能用 C 编译器编译,因为它不是有效的 C 代码。与 C++ 不同,C 中没有引用数据类型。变量或参数名称不能以 & 符号开头。如果您想用 C 语言编写,请使用 C 编译器。最流行的编译器是 GNU C 编译器 (GCC) https://gcc.gnu.org/,而更轻便的替代品是 TinyCC,它们都在大多数常见的发行版存储库中可用。
您的第一个代码示例使用指向参数(即地址)的指针。你称之为'reference',理论上并没有错。但是因为在 C++ 中引用是不同的东西(见下文),所以将这个术语用于指针是相当不常见的。
您的第二个代码示例确实使用了引用。但这不是 C。引用是 C++ 的一个特性。这意味着您使用的编译器接受这个(并且可能是 C++ 编译器)。
C++ 是 C 的超集,这就是为什么程序看起来是 C 但使用 C++ 功能的原因。
您发布的代码不能用 C 编译器编译,因为它不是有效的 C 代码。与 C++ 不同,C 中没有引用数据类型。变量或参数名称不能以 & 符号开头。如果你想用C写,请使用C编译器。
这里有一些我不明白的地方。也许有人可以阐明它。
我知道数据操作的标准方法是传递对函数的引用并更改函数中的数据。像这样:
#include <stdio.h>
#include <stdlib.h>
void function2( float *param) {
printf("I've received value %f\n", *param);
(*param)++;
}
int main(void) {
float variable = 111;
function2(&variable);
printf("variable %f\n", variable);
return 0;
}
当用 (&variable) 调用 function2 时,我希望函数可以更改数据。 到目前为止没有问题。
但为什么这也有效?
#include <stdio.h>
#include <stdlib.h>
void function2( float ¶m) {
printf("I've received value %f\n", param);
(param)++;
}
int main(void) {
float variable = 111;
function2(variable);
printf("variable %f\n", variable);
return 0;
}
据我了解,当调用 function2(variable) 时,会将“variable”值的副本传递给该函数。但是尽管如此,“变量”的值在函数调用后发生了变化。
当阅读这样的代码时,无论函数内部发生什么,我都不会期望“变量”的数据发生变化。
变体 1 需要一个 指针 作为参数。因此,您需要显式传入 &variable
.
变体 2 需要一个 reference 作为参数。它们 有点 就像一个指针,因为它们仍然指向内存中的原始位置,但也有点不同,因为它们在类型方面不仅仅是一个地址在记忆中。就像,如果我没记错的话,你不能用引用做时髦的指针运算。
如您所见,如果函数需要引用作为参数,编译器将知道该怎么做,而无需您显式创建引用。
此外,如您所见,如果有人调用您的函数但没想到它会更改原始数据,这可能会带来令人讨厌的意外。这就是为什么在干净的代码中你不会引入意想不到的副作用;如果一个函数弄乱了输入,那应该是它唯一做的事情,而且应该非常明确。
要最终获得不改变原始版本的变体,
void function2( float param)
在函数声明中。没有 *
也没有 &
。在这种情况下,该函数没有获得指针或引用,而只是一个浮点值,它现在将是输入参数的 copy,因此不会更改您的变量。
这个参数声明
void function2( float ¶m) {
不正确。在 C 中没有引用。这样的函数声明将在存在引用的 C++ 中有效。
在 C++ 中调用函数时
function2(variable);
没有创建变量的副本。函数引用main中声明的原始变量。
您发布的代码不能用 C 编译器编译,因为它不是有效的 C 代码。与 C++ 不同,C 中没有引用数据类型。变量或参数名称不能以 & 符号开头。如果您想用 C 语言编写,请使用 C 编译器。最流行的编译器是 GNU C 编译器 (GCC) https://gcc.gnu.org/,而更轻便的替代品是 TinyCC,它们都在大多数常见的发行版存储库中可用。
您的第一个代码示例使用指向参数(即地址)的指针。你称之为'reference',理论上并没有错。但是因为在 C++ 中引用是不同的东西(见下文),所以将这个术语用于指针是相当不常见的。
您的第二个代码示例确实使用了引用。但这不是 C。引用是 C++ 的一个特性。这意味着您使用的编译器接受这个(并且可能是 C++ 编译器)。
C++ 是 C 的超集,这就是为什么程序看起来是 C 但使用 C++ 功能的原因。
您发布的代码不能用 C 编译器编译,因为它不是有效的 C 代码。与 C++ 不同,C 中没有引用数据类型。变量或参数名称不能以 & 符号开头。如果你想用C写,请使用C编译器。