但我看不出有什么方法可以扩展解决方案,
移动两个这样的指针的情况,
一次
The 2 are equivalent and neither one
changes 2 pointers at once.
The problem in move_pointer()
void move_pointer(const double** pointer){*pointer++;}
考虑这个图像,代码和输出并排(源代码在下面)
这只是操作符和地址变化的可视化.32-使用位平台,仅用于较短的地址
从代码
p = *ppInt++; // a
printf("\
[1] *p is %d\n\
ppInt now points to 0x%p\n", *p, ppInt);
这样,p
指向a[]
,所以*p
是a[0]
,也就是17
.但是ppInt
是递增的,下一个命令显示首先运行的是什么:++
p = *ppInt; // b
printf(" [2] *p is %d\n", *p);
它会打印出
[2] *p is 420
因此,将ppInt
递增为指向b[0]
而现在
p = ++*ppInt; // c
printf(" [3] *p is %d\n", *p);
fingerprint
[3] *p is 170
因为ppInt
被取消引用before并且该值在被分配给p
之前递增,所以现在指向b[1]
_
back to the original move_pointer()
###
pointer
递增
pointer
被取消引用
- 该函数结束,因此不会使用此值,
*pointer
也不会更改
++
需要运行at the address pointed by 101,所以
我们需要写下
++*pointer
或(*pointer)++
:
*pointer
被判断,我们仍然得到double*
,因为pointer
是double**
.
- 但是现在该地址处的值随后递增.这个值是来自调用者的
double**
,所以调用者中的指针会被更新.
See this table from cpp reference
例如
#include <stdio.h>
#include <stdlib.h>
void move_pointer(const double** pointer) { ++*pointer; }
const double* move_pointer_func(const double*);
void check_pointer_movement(
const double* input_vec, const int ndim);
int main(void)
{
double input_vec[] = {0.25, 0.65, 0.95, 1.2, 42., 17.};
int size = sizeof(input_vec) / sizeof(input_vec[0]);
int a[] = { 17, 42};
int b[] = {420, 170};
int* p = NULL;
int* pInt[] = {(int*)&a, (int*) & b};
printf("\
a[] is at 0x%p\n\
b[] is at 0x%p\n\
pInt address is 0x%p\n\
pInt[0] is 0x%p\n\
pInt[1] is 0x%p\n",
&a, &b,
&pInt, pInt[0], pInt[1]);
int** ppInt = (int**)&pInt;
printf(" ppInt points to 0x%p\n", ppInt);
p = *ppInt++; // a
printf("\
[1] *p is %d\n\
ppInt now points to 0x%p\n", *p, ppInt);
p = *ppInt; // b
printf(" [2] *p is %d\n", *p);
p = ++*ppInt; // c
printf(" [3] *p is %d\n", *p);
printf("\nFirst attempt:\n");
check_pointer_movement(input_vec, size);
// 2nd
const double* fwd = move_pointer_func(input_vec);
if ( (fwd - input_vec) == 1 )
printf("Second attempt worked fine!\n");
else
printf("Second attempt failed to move pointer forward!\n");
return 0;
}
const double * move_pointer_func(const double * pointer)
{
return ++pointer;
}
void check_pointer_movement(
const double* input_vec, const int ndim)
{
const double* input_vec_pointer = &input_vec[0];
for (int i = 0; i != ndim; i++)
{
printf("%.2f\n", *input_vec_pointer);
move_pointer(&input_vec_pointer);
}
}
输出
a[] is at 0x00AFF9D4
b[] is at 0x00AFF9C4
pInt address is 0x00AFF9A8
pInt[0] is 0x00AFF9D4
pInt[1] is 0x00AFF9C4
ppInt points to 0x00AFF9A8
[1] *p is 17
ppInt now points to 0x00AFF9AC
[2] *p is 420
[3] *p is 170
First attempt:
0.25
0.65
0.95
1.20
42.00
17.00
Second attempt worked fine!
注意到
move_pointer(double ** p)
void move_pointer(const double** pointer) {
++*pointer; }
这是因为++
更新了现在取消引用的double**
.
const double * move_pointer_func(const double * pointer)
const double * move_pointer_func(const double * pointer)
{
return ++pointer;
}
往往更实用,因为它可以用来更新其他指针或相同的指针.
为了测试它,我们可以用这个表达式
const double* fwd = move_pointer_func(input_vec);
if ( (fwd - input_vec) == 1 )
printf("Second attempt worked fine!\n");
else
printf("Second attempt failed to move pointer forward!\n");
因为它是C
,我们把指针按它指向的东西的大小递增,我们就有了指针算术.
double input_vec[] = {0.25, 0.65, 0.95, 1.2, 42., 17.};
int size = sizeof(input_vec) / sizeof(input_vec[0]);
这允许随意向数组添加值,并保持size
更新