指针算术

leo*_*ora 58 c pointers pointer-arithmetic

有没有人对指针算术有任何好的文章或解释(博客,例子)?图中的观众是一群学习C和C++的Java程序员.

Jer*_*ten 58

这是我学习指针的地方:http://www.cplusplus.com/doc/tutorial/pointers.html

一旦理解了指针,指针算法就很容易了.它与常规算术之间的唯一区别是,您添加到指针的数字将乘以指针所指向的类型的大小.例如,如果你有一个指向a的指针,int并且a int的大小是4个字节,那么(pointer_to_int + 4)将提前计算为16字节(4个字节)的内存地址.

所以当你写作

(a_pointer + a_number)
Run Code Online (Sandbox Code Playgroud)

在指针算术中,真正发生的是

(a_pointer + (a_number * sizeof(*a_pointer)))
Run Code Online (Sandbox Code Playgroud)

在常规算术中.


Joh*_*itb 52

首先,这个极好的视频可能有所帮助.这是关于指针的好视频.对于算术,这是一个例子:

int * pa = NULL;
int * pb = NULL;
pa += 1; // pa++. behind the scenes, add sizeof(int) bytes
assert((pa - pb) == 1);

print_out(pa); // possibly outputs 0x4
print_out(pb); // possibly outputs 0x0 (if NULL is actually bit-wise 0x0)
Run Code Online (Sandbox Code Playgroud)

(请注意,递增一个严格包含空指针值的指针是未定义的行为.我们使用NULL,因为我们只对指针的值感兴趣.通常,只指向数组元素时使用递增/递减).

以下显示了两个重要概念

  • 向指针添加/减去整数意味着将指针向前/向后移动N个元素.因此,如果int是4字节大,则在增加1之后,pa可以在我们的平台上包含0x4.
  • 用另一个指针减去指针意味着通过元素测量它们的距离.因此从pa中减去pb将产生1,因为它们具有一个元素距离.

在一个实际的例子.假设您编写了一个函数,人们为您提供了一个开始和结束指针(在C++中很常见):

void mutate_them(int *begin, int *end) {
    // get the amount of elements
    ptrdiff_t n = end - begin;
    // allocate space for n elements to do something...
    // then iterate. increment begin until it hits end
    while(begin != end) {
        // do something
        begin++;
    }
}
Run Code Online (Sandbox Code Playgroud)

ptrdiff_t是什么类型的(结束 - 开始).对于某些编译器,它可能是"int"的同义词,但对于另一个编译器,它可能是另一种类型.人们不知道,所以选择泛型typedef ptrdiff_t.

  • 讨厌指出它,但你的第一个例子是未定义的行为.;)不允许增加空指针.:) (7认同)
  • 我通常发现很难遵循视频教程,但这个笨拙的教程非常简单,很棒而且很有趣:)。只需 3 分钟即可掌握基础知识。 (2认同)

小智 6

应用NLP,称之为地址算术.人们担心和误解"指针"主要是因为他们是由错误的人和/或在错误的阶段以错误的方式用错误的例子教导的.难怪没有人"得到"它.

当教学指针时,教师继续讲述"p是指向a的指针,p的值是a的地址",依此类推.它不会工作.这是您构建的原材料.练习它,你的学生将得到它.

'int a',a是一个整数,它存储整数类型的值.'int*p',p是'int star',它存储'int star'类型值.

'a'是你如何得到'什么'整数存储在一个(尽量不使用'a'的值')'和'是你如何得到'在哪里'存储自己(试着说'地址')

'b = a'为此起作用,双方必须属于同一类型.如果a是int,则b必须能够存储int.(所以______ b,空白填充'int')

'p =&a'为此起作用,双方必须属于同一类型.如果a是整数,&a是地址,则p必须能够存储整数的地址.(所以______ p,空白填充'int*')

现在以不同的方式编写int*p以显示类型信息:

int*| p

什么是'p'?ans:它是'int*'.所以'p'是整数的地址.

int |*p

什么是'*p'?ans:它是'int'.所以'*p'是一个整数.

现在进行地址算术:

int a; 一个= 1; A = A + 1;

我们在'a = a + 1'做什么?把它想象成"下一个".因为a是一个数字,这就像说"下一个数字".由于持有1,说'下一步'将使它成为2.

//谬误的例子.你被警告了!!!int*p int a; p =&a; P = P + 1;

我们在'p = p + 1'做什么?它还在说'下一个'.这次,p不是数字而是地址.所以我们所说的是"下一个地址".下一个地址取决于数据类型,更具体地说取决于数据类型的大小.

printf("%d%d%d",sizeof(char),sizeof(int),sizeof(float));

因此地址的"下一步"将向前移动sizeof(数据类型).

这对我和我曾经教过的所有人都有用.