[英]Typecasting an array of structs (of pointers?) to be sent through winsock
[英]Is this valid typecasting use with array of structs?
在过去,我一直在努力理解指针算法、类型转换和结构数组,有时即使程序可以运行,它在技术上仍然是不正确的,所以我只想运行你们编写的这段代码并确保我正确理解所有概念。
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int id, jobType;
float salary;
} Employee;
Employee * readFileInfo(FILE *fp)
{
int numEmployees = 0;
fscanf(fp, "%d", &numEmployees); //find the int at the start of the file to indicate how many employees there are
int *array = malloc( (sizeof(int)) + ( sizeof(Employee) * numEmployees ) ); //allocate an extra spot for an integer
*array = numEmployees; //hide the number of employees one integer behind the start of the array, increment on next line
array++;
Employee *test = (Employee *) array;
for(int i = 0; i < 3; i++)
fscanf(fp, "%d %d %f", &test[i].id, &test[i].jobType, &test[i].salary); //loop through and assign each value to its proper variable
return test;
}
Employee * getEmployeeByID(Employee *arr, int ID)
{
for(int i = 0; i < *((int*)arr - 1); i++)
if(arr[i].id == ID)
return ((arr) + i); //returns address of specified employee
return 0;
}
void setID(Employee *p, int ID)
{
p->id = ID;
printf("\nset successfuly\n");
}
int getSize(Employee *arr)
{
return *((int*)arr - 1); //returns the int value hidden before start of array
}
void getAvgSalary(Employee *arr) //calculates average salary, prints out all employees who make more than that
{
float total = 0, avg = 0;
for(int i = 0; i < getSize((Employee*)arr); i++)
total += arr[i].salary;
avg = total / (float)getSize((Employee*)arr);
for(int i = 0; i < getSize((Employee*)arr); i++)
if(arr[i].salary >= avg)
printf("ID: %d has above the avg salary with a salary of $%.2f\n", arr[i].id, arr[i].salary);
}
int main(void)
{
FILE *fp = fopen("test.txt", "r+");
Employee *array = readFileInfo(fp);
Employee *emp2 = getEmployeeByID(array, 2);
setID(emp2, 5);
getAvgSalary(array);
}
test.txt
3 1 5 20000 2 1 100000 3 3 50000
基本上,该程序应该打开 test.txt,调用 readFileInfo,它在文件中找到第一个 integer(表示要跟随的员工数量),使用 3 个东西为结构数组分配 memory:大小乘以employee 结构的大小,添加一个额外的 integer 以在数组开始之前“隐藏”该大小变量。 之后,在数组上调用各种函数来试验类型转换/指针算法
任何帮助、更正、建议、观察或回应都会很棒!
代码不正确。 假设float
是double
,那么整个结构将具有 alignment 对double
的要求,这在 x86-64 上是 8 个字节。 但是您已将其强制为 alignment 4. 它具有未定义的行为,这意味着它可以工作,或者它可能会灾难性地失败。
幸运的是,这个 hack 的需求为零。 只需使用具有灵活数组成员的struct
:
typedef struct
{
int id, jobType;
float salary;
} Employee;
typedef struct {
size_t numEmployees; // use size_t for array sizes and indices
Employee employees[];
} EmployeeArray;
// allocate sizeof (EmployeeArray) space for the struct
// and sizeof (Employee) space for each array element
EmployeeArray *array = malloc(sizeof *array + sizeof (Employee) * numEmployees);
array->numEmployees = numEmployees;
array->employees[0] = ...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.