我正在尝试使用像
这样的结构来创建简单的数据库struct Employee{
char* name;
int ID;
int GPA;
int salary;
};
我知道如何使用
在堆中分配一个struct类型的指针struct Employee* emp=malloc(sizeof(Employee));
我现在的问题是我不是很擅长分配流程而且我想要 在堆中分配N个结构指针,我不能使用数组,因为直到运行时才会知道大小 有什么建议 ?
答案 0 :(得分:1)
是的,您需要动态分配内存,即为每个新struct Employee
分配一个新的堆块。
您可以在尺寸更改时使用realloc
执行此操作:
yourArrayPtr=realloc(yourArrayPtr,newsize * sizeof(struct Employee));
realloc
函数基本上为其返回值指向的数据分配新的内存量。这是扩展或缩小动态分配的数组的便捷方式。 newsize
这里是数组的新元素数,它乘以一个Employee结构的大小,呈现新数组所需的总空间量。 realloc
的返回值被分配给您的数组指针,以便它专门指向这个新分配的空间。在这种情况下,它可以像这样使用:
struct Employee* emp= NULL;
然后当你需要它时:
int n = 8;
emp = realloc (emp, n * sizeof(struct Employee));
请记住,您仍需要free
这段记忆。
您现在可以初始化和访问此数据:
emp[3] = {value1, value2, value3, ...};
就结构而言,您还可以考虑另一种数据结构 - 链表,其中每个结构都包含指向其后继的指针。您可以在此处阅读:http://www.cprogramming.com/tutorial/c/lesson15.html
在你的情况下,它会像:
struct Employee{
char* data;
struct Employee* next;
};
答案 1 :(得分:1)
正如其他人所提到的,您可以使用malloc
在堆中创建尽可能多的员工详细信息条目,并将它们存储在动态列表中(linked list
)。我给出了一个示例代码,你可以从这里开始并扩展它,如果你想在退出之前保存员工的详细信息,你可以把它写成二进制文件并在你再次运行程序时读回来(根据你的需要) ),因为一旦你编程退出,所有数据都将丢失。
#include <stdio.h>
#include <stdlib.h>
// Max length for employee name
const unsigned int MAX_NAME_LEN = 100;
typedef struct Employee{
char* name;
unsigned int ID;
int GPA;
float salary;
} EMPLOYEE ;
typedef struct emp_database_entry {
EMPLOYEE data;
struct emp_database_entry *next;
} EMPLOYEE_ENTRY;
typedef EMPLOYEE_ENTRY* EMPLOYEE_DATABASE;
// to create a new employee
EMPLOYEE_ENTRY* createEmployee() {
EMPLOYEE_ENTRY *newEmp = (EMPLOYEE_ENTRY*)malloc(sizeof(EMPLOYEE_ENTRY));
printf("Enter Employee Name:");
newEmp->data.name = (char*)malloc( MAX_NAME_LEN * sizeof(char) );
scanf("%s",newEmp->data.name);
printf("Enter employee ID:");
scanf("%u",&newEmp->data.ID);
printf("Enter employee GPA:");
scanf("%u",&newEmp->data.GPA);
printf("Enter employee salary:");
scanf("%f",&newEmp->data.salary);
newEmp->next = 0;
return (newEmp);
}
// add a new employee to database
EMPLOYEE_DATABASE addEmployee(EMPLOYEE_DATABASE db) {
EMPLOYEE_ENTRY *newEmp = createEmployee();
if(db == NULL) {
// add the first entry
db = newEmp;
} else {
// add it to the top
newEmp->next = db;
db = newEmp;
}
return (db);
}
// Search for Employee using ID
EMPLOYEE_ENTRY* searchEmployee(EMPLOYEE_DATABASE db, unsigned int ID) {
EMPLOYEE_ENTRY *employee = db;
if(employee == NULL) {
printf("There are no Employees in the database\n");
return (NULL);
}
// Search till the end, if a match is found return the
// pointer to employee
while( employee != NULL ) {
if( employee->data.ID == ID )
return (employee);
else
employee = employee->next;
}
return (NULL);
}
void printOneEmployee( EMPLOYEE_ENTRY *employee ) {
printf("Employee Details\n");
printf("Name : %s\n",employee->data.name);
printf("ID : %u\n",employee->data.ID);
printf("GPA : %d\n",employee->data.GPA);
printf("Salary: %f\n\n",employee->data.salary);
}
// Print all employee details
void printAllEmployee( EMPLOYEE_DATABASE db ) {
EMPLOYEE_ENTRY *employee = db;
// traverse till the end and print one by one
while( employee != NULL ) {
printOneEmployee(employee);
employee = employee->next;
}
}
// freeing allocated memory
void freeDatabase(EMPLOYEE_DATABASE db) {
EMPLOYEE_DATABASE employee = 0;
while( db != NULL ) {
employee = db;
db = employee->next;
free(employee->data.name);
free(employee);
}
}
void displayOption( EMPLOYEE_DATABASE db ) {
int option = -1;
while( option != 5 ) {
printf("\nEmployee DataBase\n");
printf("1: Add a Employee\n");
printf("2: Search Employee\n");
printf("3: Print All Employee\n");
printf("4: Exit\n");
printf("Enter a number for the choice: ");
scanf("%d",&option);
if( option > 4 || option < 0 ) {
option = -1;
}
switch( option ) {
case 1:
db = addEmployee(db);
break;
case 2:
int ID;
if(db != NULL){
printf("Enter the Employee ID: ");
scanf("%d",&ID);
printf("Search Result1: ");
printOneEmployee(searchEmployee(db, ID));
}
else
printf("No Employees in the database\n");
break;
case 3:
printAllEmployee(db);
break;
case 4:
freeDatabase(db);
printf("DataBase Deleted\nExiting..");
exit(0);
default:
printf("Invalid Option!. Try Again!.\n");
}
}
}
int main() {
EMPLOYEE_DATABASE db = 0;
displayOption(db);
return (0);
}
答案 2 :(得分:0)
当然,如果使用C99,则可以使用数组。在C99中,您可以执行以下操作:
scanf("%d", &N);
struct Employee emp[N];
emp[0].ID = 123;
如果您使用的是gcc(或MinGW),请务必使用-std = c99进行编译
另一方面,如果你只想在堆上创建一个数组,你可以这样做:
scanf("%d", &N);
struct Employee* emp=malloc(N*sizeof(Employee));
emp[0].ID =123;
...
// do not forget to deallocate emp
free(emp);