*(p + i)语法,p为int *

时间:2016-06-21 00:56:19

标签: c pointers memory

我在软件安全上启动了一个单元 - 在一些预读中,我遇到了以下指针语法,我不确定是否理解。

int  x = 20;
int* p = &x;
int  k = *(p+1);

示例中的 k 是什么?

我知道我是否有这样的数组:

int  j[10] = {0};
int  k  = *(j+1);

此类语法将在数组 j 的位置1处取消引用int(系统' s sizeof(int))。

那么这如何与上面的非数组示例一起使用?

4 个答案:

答案 0 :(得分:2)

向指针添加*(p+1)的指针算术int语法等同于p[i]。它假定p指向足够大小的块,否则取消引用会导致未定义的行为。

请注意,您不需要使用数组new初始化指针。您可以在自动内存中使用数组,指向现有数组,甚至指向另一个数组的中间,如下所示:

int data[20] = {0, 1, 2, 3, 4, 5, 6, ...};
int *p = &data[5]; // Point to element at index five
int x = *(p+1);    // Access element at index six

答案 1 :(得分:2)

指向值的指针与指向数组第一个元素的指针无法区分。

因此int*p = &x是指向数组的第一个元素的指针,其中只分配了一个元素。现在*(p+1)正在访问该数组的第二个元素 - 这是访问元素超出数组范围并且是未定义的行为(Array index out of bound in C)。此类操作的有效结果范围从世界销毁到无操作。

一个可能的情况是*(p+1)将引用p本身的整体/部分,因为通常变量是按顺序分配的。所以很有可能没有什么了不起的事情,并且bug会在一段时间内被忽视。代码审查和一般关注此类代码是防止这些代码的良好做法。

答案 2 :(得分:1)

在第一个示例中,您将在x之后直接指向内存中的项目。 x之后的内存将是p的地址,包含在p中。

请记住,这是一种概括,这可能会根据一些事情而改变,因此它是未定义的行为。尝试添加以下行:

printf("&x: %p\n p: %p\n&k: %p\n k: %08x\n", &x, p, &k, k);

并在main中运行代码。这应该打印出内存地址和k的十六进制值。它应该让你更清楚地了解内存中究竟发生了什么。

请注意,如果更改变量的顺序,输出将会更改。你应该习惯记忆是如何工作的以及为什么这种事情是未定义的行为(因此除了学习目的之外不应该用于任何事情)。

答案 3 :(得分:1)

这是我用这种语法编写的代码示例,它将一个int分解为它的组成字节。

#include <stdio.h>

int main(void) {
    int  i = 9;
    int* p = &i;

    char* c = (char*)&i; 
    printf("%08X\n", *c);
    printf("%08X\n", *(c+1));
    printf("%08X\n", *(c+2));
    printf("%08X\n", *(c+3));

    return 0;
}

➜  tmp git:(master) ✗ ./q3          
00000009
00000000
00000000
00000000