简单的指针算术问题

时间:2012-04-16 00:55:10

标签: c pointers

问题1:

我正在阅读K& R书,我对某些事情感到有些困惑。 我对一些简单的指针运算有点困惑。 如果我说

char (*a)[10];

我知道我刚刚声明了一个指向10个字符数组的指针。 首先,因为我没有malloc,所有这些仍然保留在堆栈上吗?所以堆栈中有这个指针指向大小为10的char数组的开头吗?

现在,如果我想访问数组中的第二个元素,我还能这么做吗? *(A + 2 *的sizeof(char)的)?或者在这种情况下不起作用?

问题2:

如果我有

int* a = malloc(10*sizeof(int));

如果我想从整数数组中获取第二个字节, 我愿意:

*((char*)((char*)a+2))

这是对的吗?

谢谢。

3 个答案:

答案 0 :(得分:2)

第一件事

In C/C++, array index starts from 0 instead of 1。因此,如果要访问第二个元素,则使用索引1,而不是2!

回答1

char (*a)[10];

是的,这是一个指向大小为10的数组的指针。指针本身位于堆栈上。但它没有指向任何有效数组,对于这一行,这意味着它是单元化的。

要初始化指针,

char b[2][10] = {"123456789", "abcdefghi"};
// initialize pointer "a"
char (*a)[10] = b;

要访问“second”元素,在这种情况下为“2”,您可以使用

char (*a)[10] = b;
// access the element at 1st row, 2nd column
printf("%c\n", a[0][1]);

回答2

您想要访问第二个字节。但是,元素索引从0开始而不是1,因此第2个字节应该使用“+1”而不是“+2”!

*((char*)a+1);

答案 1 :(得分:1)

当你声明指针时,它还没有指向任何东西。如果要将它放在堆栈上,则需要声明一个10字符大小的数组并将其地址分配给(*a)[10]。至于访问第二个元素,大多数编译器可以为下一个元素执行*(a+1)(因此对于4字节的int,*(a + 1)是第二个元素,而*(a + 4)是第四个元素(不是第四个字节)。

char (*a)[10];
char arrayTest[10];
a=&arrayTest;

关于第二个问题,获取第二个字节将是*a,然后只需执行右移:

char Test= ((*a)&0x7FFF)>>8;

答案 2 :(得分:1)

问题1:

  

首先,因为我没有malloc,所有这些仍然保留在堆栈上吗?

指针在堆栈上声明,但它还没有指向任何东西。你需要做类似的事情:

char (*a)[10];
char array[10];
a = &array;

否则a不指向任何内容,尝试访问它会导致问题。

  

现在,如果我想访问数组中的第二个元素,我还会*(a + 2 * sizeof(char))

您不需要说sizeof(char),因为编译器会使用您正在使用的指针或数组的类型计算出添加的大小。另外,如果你想要第二个元素,你需要加1而不是2(因为数组/指针从零开始索引)。

  • 如果您想要指向的数组中的第二个元素,则可以(*a)+1(*a)[1]

  • 如果您的指针指向多个数组,并且您想要第二个数组,那么*(a+1)a[1]就是您想要的。


问题2:

(下次最好打开多个问题:)

  

如果我想从整数数组中获取第二个字节,我会这样做:*((char*)((char*)a+2))

首先,当你说:

时,要认识到这一点很重要
int* a = malloc(10*sizeof(int));

你有一个指向内存块的指针,有足够的空间容纳10个整数 - 这不是一个数组。如果这令人困惑,请参阅C-FAQ on pointers and arrays

现在,如果你想要指向内存块的第二个字节,你可以说:

char second_byte = *((char*)a+1);

因为强制转换的优先级高于添加,所以a在执行添加时被视为char*。但是,为了尽量减少阅读代码时误解的可能性,我可能会写:

char second_byte = *(((char*)a)+1);

或更好:

char second_byte = ((char*)a)[1];

相反。请注意,原始示例中的额外强制转换是不必要的。