简体   繁体   English

指针算术:char指针作为结构的成员

[英]pointer arithmetic : char pointer as a member of a struct

I took an example structure from K&R (page: 133) and tried a few pointer arithmetic on a pointer to an array of structure . 我从K&R(第133页)中获取了一个示例structure ,并在pointer structure arraypointer上尝试了一些pointer运算。

#include <stdio.h>
// struct example from K&R
struct key {
    char *word;
    int count;
}keytab[] = {
    "auto",0,
    "break",0,
    "const",0,
    /*.....*/
    "case",0
};
int main () { 
    struct key *ptr1 = keytab;
    printf("%d\n",sizeof(struct key));

    //check1
    printf("%s\n",ptr1++->word); //1
    printf("%s\n",ptr1->word);   //2

    //check2
    printf("%s\n",++ptr1->word);  //3
    printf("%s\n",++ptr1->word);  //4

    //check3
    printf("%s\n",ptr1++->word);  //5
    printf("%s\n",ptr1->word);  //6 ??
}

output: 输出:

8
auto
break
reak
eak
eak
const

I could understand the output of 3rd and 4th printf with the help of operator precedence. 我可以借助运算符优先级来理解3rd4th printf的输出。

But when it comes to 5th and 6th printf , how ptr1 has incremented in here ? 但是,当谈到5th6th printfptr1在这里如何增加? output of the program shows similar behaviour as with 1st & 2nd printf s. 程序的输出显示出与1st & 2nd printf相似的行为。 If ptr1 increments in step of one struct size (here 8 bytes) then how it aligns itself to the starting of a keytab[2] . 如果ptr1以一个结构大小(此处为8个字节)的步长递增,那么它将如何与keytab[2]的开始对齐。

I might have understood wrong or this last query may be invalid, please explain ! 我可能理解错了,或者这最后一个查询可能无效,请解释!

Thanks for the help! 谢谢您的帮助!

So, the 3 and 4 prints increment ptr1->word. 因此,第3和第4个打印将递增ptr1-> word。 After they are executed, ptr1->word points to "eak". 执行它们后,ptr1-> word指向“ eak”。

Print 5 prints that unmodified value first and then increments ptr1, which then points to the next word in the list, "const". Print 5首先打印该未修改的值,然后递增ptr1,然后指向列表中的下一个单词“ const”。

This all is about operator precedence, as you stated but also about the effect of prefix and postfix ++ operator. 正如您所说,所有这些都与运算符优先级有关,而且还与前缀和后缀++运算符的作用有关。 The side effect of those is the same, but the first returns the new value, while the second the old one. 它们的副作用是相同的,但是第一个返回新值,而第二个返回旧值。

This expression: 该表达式:

++ptr1->word

does not increment ptr1 pointer. 不增加ptr1指针。 Due to operator precedence it's grouped as ++(ptr1->word) , because -> operator binds more tightly than prefix ++ . 由于运算符的优先级,它被归类为++(ptr1->word) ,因为->运算符的绑定比前缀++更紧密。 What it means is that it increments the word member of currently pointed object of the struct. 这意味着它会增加结构当前指向的对象的word成员。

If ptr1 increments in step of one struct size (here 8 bytes) then how it aligns itself to the starting of a keytab[2]. 如果ptr1以一个结构大小(此处为8个字节)的步长递增,那么它将如何与keytab [2]的开始对齐。

But ptr1 is always pointing to an element of keytab. 但是ptr1 始终指向keytab的元素。 It's not allowed to point part-way through an element, and that never happens. 不允许指向某个元素的中途,这种情况永远不会发生。

The reason you see reak , and then eak , is that the keytab entry pointed to by ptr1 has been changed in-place. 您看到reak ,然后看到eak的原因是, ptr1 指向的keytab条目已就地更改。

That is, ++ptr1->word doesn't change ptr1 at all . 也就是说, ++ptr1->word不改ptr1 可言 You can check - just print its value before and after. 您可以检查-只需在其前后打印其值即可。 That expression changes the value of word inside your keytab. 这表情变化的价值word的密钥表 After line #3, keytab[1].word has changed (been incremented) so it points to "reak" . 在第3行之后, keytab[1].word已更改(已增加),因此指向"reak"

When you finally increment ptr1 again (just after #5 is printed), you're still incrementing it from &keytab[1] to &keytab[2] . 当最终再次增加ptr1时(在打印#5之后),您仍在将其从&keytab[1] &keytab[2]&keytab[2] The fact that you modified the inside of keytab[1] doesn't affect that at all. 您修改keytab[1]内部的事实完全不会影响。

I could understand the output of 3rd and 4th printf with the help of operator precedence 我可以借助运算符优先级来理解第三和第四printf的输出

It seems you correctly realised most of this, but overlooked that changing ptr1->word doesn't affect the value of ptr1 itself. 看来您正确地理解了其中的大部分内容,但是忽略了更改ptr1->word不会影响ptr1本身的值。

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

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