Use arr
directly instead of arr_ptr
will cause error!!! why?
#include <stdio.h>
int main()
{
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
printf("%d\n", *arr++); // error: lvalue required as increment operand
return 0;
}
array name 只有在兩種情況下會被轉成指向 array 第一個元素的 pointer:
- 做為 function parameter 時:
int func(int arr[])
等價於int func(int *arr)
- 做為 expression 時:
int *arr_ptr = arr;
所以說,上例中的 *arr++
因為 arr
在此並非 expression 也非 function parameter,因此不會被轉成指向 array 第一個元素的 pointer,因此會出現 error。
Error message: lvalue required as increment operand 在說的就是:在此 arr
為 pointer to a array(arr
),而非 pointer to the first element of arr(i.e. arr[0]
),又 arr
的 address 不能被更改,因此 *arr++
會產生 error。
使用 lldb(on MacOS M1 chip) 檢查可看出 arr
為 int[4]
而 arr_ptr
為 int *
。
(lldb) p arr
(int[4]) $0 = ([0] = 0, [1] = 0, [2] = -498728925, [3] = 2073223340)
(lldb) p arr_ptr
(int *) $1 = 0x000000010000c100
以下使用 int* arr_ptr = arr
,就不會有沒辦法被 convert 成 pointer 的問題。
需要特別注意的是 *arr_ptr++
系列,++
和 *
之間的先後作用關係。
#include <stdio.h>
int main()
{
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int* arr_ptr = arr;
// dereferece and then increment the value pointed by arr_ptr
printf("%p\n", arr); // 0x7fff3f86d430
printf("%p\n", arr_ptr); // 0x7fff3f86d430
printf("%d\n", ++*arr_ptr); // 2
printf("%p\n", arr_ptr); // 0x7fff3f86d430
printf("%d\n", ++(*arr_ptr)); // 3
printf("%p\n", arr_ptr); // 0x7fff3f86d430
printf("%d\n", ++*(arr_ptr)); // 4
printf("%p\n", arr_ptr); // 0x7fff3f86d430
for(int i = 0; i < 9; i++) {
printf("%d ", arr[i]);
}
// arr: [4 2 3 4 5 6 7 8 9]
printf("\n");
// move pointer to the next int position
// but retern the old content
printf("%d\n", *arr_ptr++); // 4
printf("%p\n", arr_ptr); // 0x7fff3f86d434
// arr_ptr is at 2, dereference it and then increment it(2 -> 3),
// but return the old content(2)
printf("%d\n", (*arr_ptr)++); // 2
printf("%p\n", arr_ptr); // 0x7fff3f86d434
printf("%d\n", *(arr_ptr)++); // 3
printf("%p\n", arr_ptr); // 0x7fff3f86d438
for(int i = 0; i < 9; i++) {
printf("%d ", arr[i]);
}
// 4 3 3 4 5 6 7 8 9
printf("\n");
// arr_ptr moves to the next int position
// and then dereference it
printf("%d\n", *++arr_ptr); // 4
printf("%p\n", arr_ptr); // 0x7fff3f86d43c
printf("%d\n", *++(arr_ptr)); // 5
printf("%p\n", arr_ptr); // 0x7fff3f86d440
printf("%d\n", *(++arr_ptr)); // 6
printf("%p\n", arr_ptr); // 0x7fff3f86d444
return 0;
}