【发布时间】:2020-05-10 21:18:32
【问题描述】:
参考下面的代码,我可以这样往结构的成员中插入数据:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
struct user {
int id;
char username[20];
char password[20];
};
int main(void) {
struct user *p;
p = malloc(sizeof(struct user));
p->id = 27;
strcpy(p->username, "roberto");
strcpy(p->password, "P4_4t4r");
printf("Id = %d\n", p->id);
printf("Username = %s\n", p->username);
printf("Password = %s\n", p->password);
return 0;
}
上面提到的程序可以运行。现在,我想尝试使用指针算法,用于赋值和显示结构成员,我想我会这样做:
#include <stdlib.h>
#include <stdio.h>
struct user {
int id;
char username[20];
char password[20];
};
int main(void) {
struct user *p;
p = malloc(sizeof(struct user));
*(int*)p = 27; // id = 27
p += 4; // int is 4 bytes, so let's move 4 bytes ...
*(char*)p = 'r';
*(char*)++p = 'o';
*(char*)++p = 'b';
*(char*)++p = 'e';
*(char*)++p = 'r';
*(char*)++p = 't';
*(char*)++p = 'o';
*(char*)++p = '\0';
p += 13;
*(char*)p = 'P';
*(char*)++p = '4';
*(char*)++p = '_';
*(char*)++p = '4';
*(char*)++p = 't';
*(char*)++p = '4';
*(char*)++p = 'r';
*(char*)++p = '\0';
p -= 31; // I put the pointer back to the first byte of the memory block
// Output
printf("Id = ");
printf("%d\n", *(int*)p);
p += 4;
printf("Username = ");
printf("%c", *(char*)p); // r
printf("%c", *(char*)++p); // o
printf("%c", *(char*)++p); // b
printf("%c", *(char*)++p); // e
printf("%c", *(char*)++p); // r
printf("%c", *(char*)++p); // t
printf("%c\n", *(char*)++p); // o
++p; // \0
p += 13;
printf("Password = ");
printf("%c", *(char*)p); // P
printf("%c", *(char*)++p); // 4
printf("%c", *(char*)++p); // _
printf("%c", *(char*)++p); // 4
printf("%c", *(char*)++p); // t
printf("%c", *(char*)++p); // 4
printf("%c\n", *(char*)++p); // r
++p; // \0
printf("\n");
p -= 31; // I put the pointer back to the first byte of the memory block
return 0;
}
我从两个来源的比较中意识到右箭头选择 (->) 运算符非常有用。 现在我想到了使用指针的算术将值分配给结构的成员,并使用右箭头选择 (->) 运算符显示它们的内容,如下所示:
#include <stdlib.h>
#include <stdio.h>
struct user {
int id;
char username[20];
char password[20];
};
int main(void) {
struct user *p;
p = malloc(sizeof(struct user));
*(int*)p = 27;
p += 4;
*(char*)p = 'r';
*(char*)++p = 'o';
*(char*)++p = 'b';
*(char*)++p = 'e';
*(char*)++p = 'r';
*(char*)++p = 't';
*(char*)++p = 'o';
*(char*)++p = '\0';
p += 13;
*(char*)p = 'P';
*(char*)++p = '4';
*(char*)++p = '_';
*(char*)++p = '4';
*(char*)++p = 't';
*(char*)++p = '4';
*(char*)++p = 'r';
*(char*)++p = '\0';
p -= 31;
printf("Id = %d\n", p->id);
printf("Username = %s\n", p->username);
printf("Password = %s\n", p->password);
return 0;
}
但在后一种情况下,我得到了这个结果:
Id = 27
Username =
Password =
谁能告诉我哪里错了?
【问题讨论】:
-
您是否尝试过在调试器中运行上述程序并查看它是否符合您的想法?
-
你用的是什么编译器?对于您正在做的工作,您要么需要打包结构,要么需要了解编译器如何对齐结构中的字段。
-
指针以指向对象的步长递增,而不是字节。也就是说,将
int指针增加3 意味着移动3*sizeof(int)字节(注意sizeof(int)不一定是4)。 -
前两个程序给了我想要的价值。只有最后一个不起作用,但仅在可视化中。我在 64 位苹果上使用 gcc --version Apple clang 版本 11.0.3 (clang-1103.0.32.59)。
标签: c struct pointer-arithmetic