C 中变量的作用域
Scope Of variable in C
看看下面给出的代码,这里的价格、数量和金额是我们传递给扩展的主函数的局部值,其中价格、数量和金额是函数局部的格式参数。我的问题是,在不使用指针的情况下,void extend 的局部数量变化将如何反映在 main 中。
#include <stdio.h>
void extend(float[], float[], double[]);
int main(void) {
float price[10] = { 10.62, 14.89, 13.21, 16.55, 18.62, 9.47, 6.58, 18.32, 12.15, 3.98 };
float quantity[10] = { 4, 8.5, 6, 8.35, 9, 15.3, 3, 5.4, 2.9, 4.8 };
double amount[10] = { 0 };
extend(price, quantity, amount);
for (int i = 0; i < 10; i++) {
printf("%f ", amount[i]);
}
return 0;
}
void extend(float PRICE[], float QUANTITY[], double amount[]) {
for (int i = 0; i < 10; i++) {
amount[i] = PRICE[i] * QUANTITY[i];
}
}
你错了。实际上该函数使用指针。这个函数声明
void extend(float[], float[], double[]);
被编译器调整为如下声明
void extend(float *, float *, double *);
来自 C 标准(6.7.6.3 函数声明符(包括原型))
7 A declaration of a parameter as ‘‘array of type’’ shall be adjusted
to ‘‘qualified pointer to type’’, where the type qualifiers (if any)
are those specified within the [ and ] of the array type derivation.
If the keyword static also appears within the [ and ] of the array
type derivation, then for each call to the function, the value of the
corresponding actual argument shall provide access to the first
element of an array with at least as many elements as specified by the
size expression.
并且当函数被调用时
extend(price, quantity, amount);
数组指示符 price、quantity 和 amount 被隐式转换为指向其第一个元素的指针。所以实际上数组的元素是通过指向第一个元素的指针间接引用传递的。使用指针算法可以在函数内更改数组 amount 的元素
amount[i] = PRICE[i] * QUANTITY[i];
来自 C 标准(6.3.2.1 左值、数组和函数指示符)
3 Except when it is the operand of the sizeof operator or the unary &
operator, or is a string literal used to initialize an array, an
expression that has type ‘‘array of type’’ is converted to an
expression with type ‘‘pointer to type’’ that points to the initial
element of the array object and is not an lvalue. If the array object
has register storage class, the behavior is undefined.
注意,例如这个表达式 amount[i]
等同于 *( amount + i )
.
来自 C 标准(6.5.2.1 数组下标)
2 A postfix expression followed by an expression in square brackets []
is a subscripted designation of an element of an array object. The
definition of the subscript operator [] is that E1[E2] is identical to
(*((E1)+(E2))). Because of the conversion rules that apply to the
binary + operator, if E1 is an array object (equivalently, a pointer
to the initial element of an array object) and E2 is an integer,
E1[E2] designates the E2-th element of E1 (counting from zero).
看看下面给出的代码,这里的价格、数量和金额是我们传递给扩展的主函数的局部值,其中价格、数量和金额是函数局部的格式参数。我的问题是,在不使用指针的情况下,void extend 的局部数量变化将如何反映在 main 中。
#include <stdio.h>
void extend(float[], float[], double[]);
int main(void) {
float price[10] = { 10.62, 14.89, 13.21, 16.55, 18.62, 9.47, 6.58, 18.32, 12.15, 3.98 };
float quantity[10] = { 4, 8.5, 6, 8.35, 9, 15.3, 3, 5.4, 2.9, 4.8 };
double amount[10] = { 0 };
extend(price, quantity, amount);
for (int i = 0; i < 10; i++) {
printf("%f ", amount[i]);
}
return 0;
}
void extend(float PRICE[], float QUANTITY[], double amount[]) {
for (int i = 0; i < 10; i++) {
amount[i] = PRICE[i] * QUANTITY[i];
}
}
你错了。实际上该函数使用指针。这个函数声明
void extend(float[], float[], double[]);
被编译器调整为如下声明
void extend(float *, float *, double *);
来自 C 标准(6.7.6.3 函数声明符(包括原型))
7 A declaration of a parameter as ‘‘array of type’’ shall be adjusted to ‘‘qualified pointer to type’’, where the type qualifiers (if any) are those specified within the [ and ] of the array type derivation. If the keyword static also appears within the [ and ] of the array type derivation, then for each call to the function, the value of the corresponding actual argument shall provide access to the first element of an array with at least as many elements as specified by the size expression.
并且当函数被调用时
extend(price, quantity, amount);
数组指示符 price、quantity 和 amount 被隐式转换为指向其第一个元素的指针。所以实际上数组的元素是通过指向第一个元素的指针间接引用传递的。使用指针算法可以在函数内更改数组 amount 的元素
amount[i] = PRICE[i] * QUANTITY[i];
来自 C 标准(6.3.2.1 左值、数组和函数指示符)
3 Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined.
注意,例如这个表达式 amount[i]
等同于 *( amount + i )
.
来自 C 标准(6.5.2.1 数组下标)
2 A postfix expression followed by an expression in square brackets [] is a subscripted designation of an element of an array object. The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))). Because of the conversion rules that apply to the binary + operator, if E1 is an array object (equivalently, a pointer to the initial element of an array object) and E2 is an integer, E1[E2] designates the E2-th element of E1 (counting from zero).