简体   繁体   English

简单的指针算术问题

[英]Simple pointer arithmetic problems

Question 1: 问题1:

I was reading the K&R book, and i got a little confused about something. 我正在阅读K&R的书,我对某些事情感到有些困惑。 I'm a little confused on some simply pointer arithmetic. 我对一些简单的指针运算有点困惑。 If I say 如果我说

char (*a)[10];

I know that I just declared a pointer to an array of 10 chars. 我知道我刚刚声明了一个指向10个字符数组的指针。 Firstly, because I didn't malloc, this is still all kept on the stack right? 首先,因为我没有malloc,所有这些仍然保留在堆栈上吗? So there is this pointer in the stack that is pointing to the start of the char array of size 10 right? 所以堆栈中有这个指针指向大小为10的char数组的开头吗?

Now, If I want to access the second element in the array, would I still do *(a+2*sizeof(char))? 现在,如果我想访问数组中的第二个元素,我还会做*(a + 2 * sizeof(char))吗? Or would that not work in this case? 或者在这种情况下不起作用?

Question 2: 问题2:

If I had 如果我有

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

If I wanted to get the second byte from the integer array, I would do: 如果我想从整数数组中获取第二个字节 ,我会这样做:

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

Is this correct? 这个对吗?

Thank you. 谢谢。

First Thing First 第一件事

In C/C++, array index starts from 0 instead of 1 . In C/C++, array index starts from 0 instead of 1 So if you want to access the second element, you use index 1, not 2 ! 因此,如果要访问第二个元素,则使用索引1,而不是2!

Answer 1 答案1

char (*a)[10];

Yes, this is a pointer to an array of size 10. The pointer itself is on the stack. 是的,这是一个指向大小为10的数组的指针。指针本身位于堆栈上。 But it doesn't point to any valid array, for this single line, which means it's unitialized. 但它没有指向任何有效的数组,对于这一行,这意味着它是单元化的。

To initialize your pointer, 要初始化指针,

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

To access the "second" element, "2" in this case, you use, 要访问“second”元素,在这种情况下为“2”,您使用,

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

Answer 2 答案2

You want to access the 2nd byte. 您想要访问第二个字节。 However, the element index start from 0 instead of 1, so you should use "+1" instead of "+2" for the 2nd byte! 但是,元素索引从0开始而不是1,因此对于第2个字节应该使用“+1”而不是“+2”!

*((char*)a+1);

when you declare the pointer, its not pointing to anything quite yet. 当你声明指针时,它还没有指向任何东西。 you will need to declare a size 10 character array and assign its address to (*a)[10] if you want it to be on stack. 你需要声明一个10号字符大小的数组并将其地址分配给(*a)[10]如果你想要它在堆栈上。 As for accessing the second element, most compilers you can do *(a+1) for the next element (so for an int which is 4 bytes, *(a+1) is the second element, and *(a+4) is the 4th element (NOT the 4th byte). 至于访问第二个元素,大多数编译器可以为下一个元素执行*(a+1) (因此对于4个字节的int,*(a + 1)是第二个元素,而*(a + 4)是第4个元素(不是第4个字节)。

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

with your second question, getting the second byte would be the *a and then simply do a rightshift: 在第二个问题中,获取第二个字节将是*a ,然后只需执行右移:

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

Question 1: 问题1:

Firstly, because I didn't malloc, this is still all kept on the stack right? 首先,因为我没有malloc,所有这些仍然保留在堆栈上吗?

The pointer is declared on the stack, but it's not pointing to anything yet. 指针在堆栈上声明,但它还没有指向任何东西。 You'd need to do something like: 你需要做类似的事情:

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

Otherwise a doesn't point to anything, and trying to access it will cause problems. 否则a不指向任何东西,并且尝试访问它将导致问题。

Now, If I want to access the second element in the array, would I still do * (a+2*sizeof(char)) 现在,如果我想访问数组中的第二个元素,我还会做* (a + 2 * sizeof(char))

You don't need to say sizeof(char) , since the compiler will work out the size of the addition for you using the type of the pointer or array you're using. 您不需要说sizeof(char) ,因为编译器将使用您正在使用的指针或数组的类型计算出添加的大小。 Also, if you want the second element, you'll need to add 1 instead of 2 (since arrays/pointers index from zero). 此外,如果你想要第二个元素,你需要加1而不是2(因为数组/指针从零开始索引)。

  • If you want the second element from the array you're pointing to, you can do (*a)+1 or alternatively (*a)[1] . 如果你想要你指向的数组中的第二个元素,你可以做(*a)+1或者(*a)[1]

  • If your pointer points to more than one array, and you want the second array, then *(a+1) or a[1] is what you want. 如果你的指针指向多个数组,并且你想要第二个数组,则*(a+1)a[1]就是你想要的。


Question 2: 问题2:

(it's really best to open multiple questions next time :) (最好是下次打开多个问题:)

If I wanted to get the second byte from the integer array, I would do: *((char*)((char*)a+2)) ? 如果我想从整数数组中获取第二个字节,我会这样做: *((char*)((char*)a+2))

Firstly, it's important to realise that when you say: 首先,当你说:当你说:

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

You have a pointer to a block of memory with enough space for 10 integers - which is not an array. 你有一个指向内存块的指针,有足够的空间容纳10个整数 - 这不是一个数组。 If this is confusing, see the C-FAQ on pointers and arrays . 如果这令人困惑,请参阅有关指针和数组C-FAQ

Now, if you want the second byte from the block of memory that a points to, you can just say: 现在,如果你想要指向内存块的第二个字节,你可以说:

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

Because the cast is a higher precedence than the addition, a is treated as a char* when the addition is performed. 因为强制转换的优先级高于加法, a在执行加法时将a视为char* However, to minimise the chance of misunderstandings when reading the code, I'd probably write: 但是,为了尽量减少阅读代码时误解的可能性,我可能会写:

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

or better: 或更好:

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

Instead. 代替。 Note that the extra cast in the original example is unnecessary. 请注意,原始示例中的额外强制转换是不必要的。

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

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