指针 - 意外输出
Pointers - unexpected output
我正在翻阅一本书,但这个例子解释不当。
据我了解,数组变量(nums
)是一个指向数组的指针。下一步我声明一个变量 choice
并给它一个数组地址的值。然后我将 choice 后面的值(我认为是 {1, 2, 3})传递给数组的最后一个元素。打印我得到的最后一个元素 1。这是怎么回事?我对指针有什么不了解?
int nums[] = {1, 2, 3};
int *choice = nums;
nums[2] = *choice;
printf("%i", nums[2]);
nums
是 而不是 指向数组的指针。 nums
是一个数组,在表达式中使用时,它被转换为指向第一个元素的指针。
所以当你这样做时:
int *choice = nums;
它使choice
指向nums
的第一个元素。然后,当您使用 *choice
时,您将获得 nums
.
第一个元素的值
As far as I understand, the array variable (nums) is a pointer to an
array
不,你错了。数组和指针是两种不同的对象。
但在极少数情况下,表达式中使用的数组会转换为指向其第一个元素的指针。
来自 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.
在此声明中
int nums[] = {1, 2, 3};
声明了一个包含三个元素的数组。
在此声明中
int *choice = nums;
声明了一个由数组指示符初始化的指针 nums
,用作初始化器的指针被隐式转换为指向其第一个(初始)元素的指针。
上面的声明其实等同于下面的声明
int *choice = &nums[0];
解引用指针我们将得到数组的第一个元素(左值)。
因此这个声明
nums[2] = *choice;
等同于
nums[2] = nums[0];
因为nums[0]
(*nums
) 等于 1 那么这个 printf
的调用
printf("%i", nums[2]);
将输出值1
。
因为choice和nums是指向数组第一个元素的指针
nums[2] = *choice;
与
相同
nums[2] = *(&choice[0]);
因此与
相同
nums[2] = choice[0];
而且,因为你做到了
int *choice = nums;
同
nums[2] = nums[0];
所以,最后 nums 的值为:
1 2 1
所以,nums[2] 是 1
我正在翻阅一本书,但这个例子解释不当。
据我了解,数组变量(nums
)是一个指向数组的指针。下一步我声明一个变量 choice
并给它一个数组地址的值。然后我将 choice 后面的值(我认为是 {1, 2, 3})传递给数组的最后一个元素。打印我得到的最后一个元素 1。这是怎么回事?我对指针有什么不了解?
int nums[] = {1, 2, 3};
int *choice = nums;
nums[2] = *choice;
printf("%i", nums[2]);
nums
是 而不是 指向数组的指针。 nums
是一个数组,在表达式中使用时,它被转换为指向第一个元素的指针。
所以当你这样做时:
int *choice = nums;
它使choice
指向nums
的第一个元素。然后,当您使用 *choice
时,您将获得 nums
.
As far as I understand, the array variable (nums) is a pointer to an array
不,你错了。数组和指针是两种不同的对象。
但在极少数情况下,表达式中使用的数组会转换为指向其第一个元素的指针。
来自 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.
在此声明中
int nums[] = {1, 2, 3};
声明了一个包含三个元素的数组。
在此声明中
int *choice = nums;
声明了一个由数组指示符初始化的指针 nums
,用作初始化器的指针被隐式转换为指向其第一个(初始)元素的指针。
上面的声明其实等同于下面的声明
int *choice = &nums[0];
解引用指针我们将得到数组的第一个元素(左值)。
因此这个声明
nums[2] = *choice;
等同于
nums[2] = nums[0];
因为nums[0]
(*nums
) 等于 1 那么这个 printf
printf("%i", nums[2]);
将输出值1
。
因为choice和nums是指向数组第一个元素的指针
nums[2] = *choice;
与
相同nums[2] = *(&choice[0]);
因此与
相同nums[2] = choice[0];
而且,因为你做到了
int *choice = nums;
同
nums[2] = nums[0];
所以,最后 nums 的值为:
1 2 1
所以,nums[2] 是 1