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))

这个对吗?

谢谢你。

4

3 回答 3

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;

要访问“第二个”元素,在本例中为“2”,请使用,

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

答案 2

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

*((char*)a+1);
于 2012-04-16T01:02:40.650 回答
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)ora[1]就是您想要的。


问题2:

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

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

首先,当你说:

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

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

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

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

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

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

或更好:

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

反而。请注意,原始示例中的额外演员表是不必要的。

于 2012-04-16T01:11:01.817 回答
1

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

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

对于你的第二个问题,获得第二个字节将是*a然后简单地做一个右移:

char Test= ((*a)&0x7FFF)>>8;
于 2012-04-16T01:02:08.920 回答