数组中的age
个 struct 字段不会形成连续的内存区域.内存中的布局类似于此:
business[0] business[1]
[ 20 bytes of name | 4 bytes of age ][ 20 bytes of name | 4 bytes of age][ 20...
您的年龄由名称数组分隔.由于C中的数组必须是连续的、没有间隙的内存区域,因此不可能只引用年龄的"数组".但是,您可以使用for循环轻松地遍历年龄,或者编写函数/定义宏以访问特定索引处的年龄:
int get_age_at_index(worker* arr, int idx) {
return arr[idx].age;
}
// OR
#define GET_AGE_AT_INDEX(arr, idx) (arr[idx].age)
这可能会允许使用与访问数组元素类似的语义,如果您所追求的是:
int my_age = get_age_at_index(business, 5);
// OR
int my_other_age = GET_AGE_AT_INDEX(business, 3);
如果您对复制数据没有意见,您可以只为20个整数分配一个数组,并从每个 struct 中复制年龄:
int ages[20] = { 0 };
for(int i; i < 20; i++) {
ages[i] = business[i].age;
}
EDIT
当您在C中有一个指向数组开头的指针(如worker* business
)并将其作为数组索引时
business points to the beginning of array:
[ worker struct 0 ][ worker struct 1 ][ worker struct 2 ]
^ ^ ^
0 * sizeof(worker) 1 * sizeof(worker) 2 * sizeof(worker) <-- offsets from the beginning of array
如果我们使指针等于第一个 struct 内存中age
个成员的地址,但将其转换为worker*
:
worker* my_hacky_pointer = (worker*) &(business[0].age);
将其增加1实际上会将其移动sizeof(worker)
,因为这是指针的类型.因此,它将移动到数组下一个元素的age
个成员.如果我们随后将此指针转换回int
并取消对其的引用*(int*) (my_hacky_pointer + 1)
,我们将得到索引1处age
字段的值.
完整示例来源:
#include <stdio.h>
#include <stdlib.h>
typedef struct worker{
char name[20];
int age;
} worker;
int main() {
worker* business = malloc(20 * sizeof(worker));
business[0].age = 5;
business[1].age = 6;
business[2].age = 99;
business[3].age = 66;
business[4].age = 78;
worker* my_hacky_pointer = (worker*) &(business[0].age);
printf("my age: %d\n", *(int*) (my_hacky_pointer + 0)); // this prints 5
printf("my age: %d\n", *(int*) (my_hacky_pointer + 1)); // this prints 6
printf("my age: %d\n", *(int*) (my_hacky_pointer + 2)); // this prints 99
printf("my age: %d\n", *(int*) (my_hacky_pointer + 3)); // this prints 66
printf("my age: %d\n", *(int*) (my_hacky_pointer + 4)); // this prints 78
}
我建议不要在任何地方使用它,有更好的方法可以获得同样的结果,这些方法在CPU上更干净、更容易,但我想有人会发现使用指针算法可以实现的结果很有趣.