繁体   English   中英

简单的指针算术问题

[英]Simple pointer arithmetic problems

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

这个对吗?

谢谢。

第一件事

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

当你声明指针时,它还没有指向任何东西。 你需要声明一个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;

问题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

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

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

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

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

或更好:

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM