活动介绍
file-type

C/C++结构体使用方法与常用操作指南

RAR文件

下载需积分: 9 | 1001KB | 更新于2025-04-22 | 150 浏览量 | 3 下载量 举报 收藏
download 立即下载
C/C++中的结构体(struct)是一种复合数据类型,它允许将不同类型的数据项组合成一个单一的类型。在C语言中,结构体被广泛用于数据组织和复杂数据表示,而在C++中,它除了用于数据组织外,还被赋予了面向对象编程的特性。结构体在内存中是顺序存储的,可以用来描述类似现实世界中的实体或事物。 ### 结构体的基础知识点: 1. **定义结构体**:使用`struct`关键字定义一个新的结构体类型,后面跟上结构体名称和结构体的内容,结构体内容包含一系列声明的数据成员。 ```c struct Person { char* name; int age; float height; }; ``` 2. **创建结构体实例**:定义结构体后,可以使用结构体类型创建变量。 ```c struct Person person1; ``` 3. **初始化结构体**:结构体可以使用初始化列表进行初始化。 ```c struct Person person2 = {"Alice", 25, 5.5}; ``` 4. **访问结构体成员**:使用点操作符`.`来访问结构体的成员。 ```c printf("Name: %s, Age: %d", person1.name, person1.age); ``` ### 结构体与链表的结合: 在C/C++中,结构体常与链表结合使用,因为结构体能够容纳多种类型的数据,非常适合用来表示链表的节点。 1. **链表节点的定义**:链表由一系列节点构成,每个节点通常包含两部分数据,一部分是存储实际数据的结构体,另一部分是指向下一个节点的指针。 ```c struct Node { struct Person data; struct Node* next; }; ``` 2. **插入节点**:链表插入节点分为头部插入、尾部插入、任意位置插入。 - 头部插入:创建一个新节点,将其next指针指向当前的头节点,然后更新头指针指向新节点。 ```c void InsertHead(struct Node** head, struct Person data) { struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); newNode->data = data; newNode->next = *head; *head = newNode; } ``` - 尾部插入:找到链表的最后一个节点,将最后一个节点的next指针指向新节点。 ```c void InsertTail(struct Node** head, struct Person data) { struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); newNode->data = data; newNode->next = NULL; if (*head == NULL) { *head = newNode; return; } struct Node* temp = *head; while (temp->next != NULL) { temp = temp->next; } temp->next = newNode; } ``` - 任意位置插入:首先找到插入位置的前一个节点,然后调整指针使新节点插入到链表中。 ```c void InsertAfter(struct Node* prevNode, struct Person data) { if (prevNode == NULL) { printf("Previous Node cannot be NULL"); return; } struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); newNode->data = data; newNode->next = prevNode->next; prevNode->next = newNode; } ``` 3. **删除节点**:删除操作需要正确处理指针,以避免内存泄漏。 - 删除头节点:直接将头指针指向下一个节点,然后释放原头节点内存。 ```c void DeleteHead(struct Node** head) { if (*head == NULL) return; struct Node* temp = *head; *head = (*head)->next; free(temp); } ``` - 删除尾节点:需要遍历整个链表找到尾节点,然后释放其内存。 ```c void DeleteTail(struct Node** head) { if (*head == NULL) return; if ((*head)->next == NULL) { free(*head); *head = NULL; return; } struct Node* temp = *head; while (temp->next->next != NULL) { temp = temp->next; } free(temp->next); temp->next = NULL; } ``` - 删除任意节点:找到待删除节点的前一个节点,然后将前一个节点的next指针指向待删除节点的下一个节点,最后释放待删除节点内存。 ```c void DeleteNode(struct Node** head, struct Node* delNode) { if (*head == NULL || delNode == NULL) return; struct Node* temp = *head; if (temp == delNode) { *head = delNode->next; free(temp); return; } while (temp->next != delNode) { temp = temp->next; } temp->next = delNode->next; free(delNode); } ``` ### 重要概念: 1. **内存分配**:在C/C++中使用结构体时,常常需要动态分配内存,这时会用到`malloc()`和`free()`函数。在C++中,可以使用`new`和`delete`来分配和释放内存。 2. **类型定义**:使用`typedef`可以为结构体定义一个新的别名,简化代码书写。 ```c typedef struct { // ... 数据成员 } Node; ``` 3. **作用域**:结构体可以定义在全局或局部作用域,但需要确保在其作用域内创建实例或进行操作。 4. **面向对象**:C++中的结构体具有类的特性,可以拥有构造函数、析构函数、成员函数和访问控制。 5. **类型安全**:相比于C中的结构体,C++提供了更多的类型安全检查。 ### 文件说明: 文件`struct.dat`和`struct.txt`可能包含结构体相关的示例代码、练习题、问题解答或其他补充材料,有助于加深对C/C++结构体的掌握。`struct.dat`可能是一个二进制文件,包含编译后的数据,而`struct.txt`则可能是一个文本文件,包含可读的结构体信息或代码片段。 通过上述描述,我们不仅了解了结构体的基础使用,还探讨了如何在C/C++中将结构体与链表操作相结合,包括节点的插入和删除。结构体是C/C++编程中非常重要的概念,它提供了对复杂数据结构操作的能力,是构建更加复杂数据结构和算法的基础。

相关推荐

filetype

// 创建Server // pStructPointer 结构体指针 // iStructPointerSize 结构体大小 // strBulidSavePath 保存路径 // pDatBuffer Dat文件数据Buffer // dwDatBufferSize Dat文件数据大小 // 成功返回TRUE,否则失败,并会设置错误信息 //1、上线结构指针 //2、上线结构大小 //3、存储DLL BUF //4、DLL大小 //1、原始DLL数据 BOOL CBulidServer::CreateServer(PVOID pStructPointer, INT iStructPointerSize, PCTSTR strBulidSavePath, PCHAR& pDatBuffer, DWORD& dwDatBufferSize) { HANDLE hFile = INVALID_HANDLE_VALUE; // 文件句柄,初始化为无效值 DWORD dwWriteSize = 0; // 实际写入的字节数 // 结构数据在Dat数据中所在位置偏移 UINT uStructDataOffset = 0; // 结构体在数据缓冲区中的偏移量 // 查找结构数据在Dat数据中所在位置偏移 uStructDataOffset = FindStructDataOffset(pStructPointer, iStructPointerSize, pDatBuffer, dwDatBufferSize); printf("偏移 = %d\n", uStructDataOffset); if (uStructDataOffset == 0) // 如果未找到结构体偏移量 { goto ERROR_HANDLE; // 跳转到错误处理 } // 创建Server文件 hFile = CreateFile(strBulidSavePath, // 文件路径 GENERIC_ALL, // 访问权限(全部) NULL, // 不共享 NULL, // 默认安全属性 CREATE_ALWAYS, // 总是创建新文件 NULL, // 无特殊属性 NULL); // 无模板文件 if (hFile == INVALID_HANDLE_VALUE) // 如果文件创建失败 { printf("创建错误·"); goto ERROR_HANDLE; // 跳转到错误处理 } // 写入结构体所在位置之前的数据 WriteFile(hFile, // 文件句柄 pDatBuffer, // 数据缓冲区 uStructDataOffset, // 要写入的字节数(结构体之前的数据) &dwWriteSize, // 接收实际写入字节数 NULL); // 不使用重叠I/O printf("pDatBuffer = 0x%x\n", pDatBuffer); if (dwWriteSize != uStructDataOffset) // 如果写入字节数不匹配 { printf("写入失败\n"); goto ERROR_HANDLE; // 跳转到错误处理 } // 写入上线数据 WriteFile(hFile, // 文件句柄 pStructPointer, // 结构体指针 iStructPointerSize, // 结构体大小 &dwWriteSize, // 接收实际写入字节数 NULL); // 不使用重叠I/O if (dwWriteSize != iStructPointerSize) // 如果写入字节数不匹配 { printf("写入失败·\n"); goto ERROR_HANDLE; // 跳转到错误处理 } // 写入结构体之后的数据 WriteFile(hFile, // 文件句柄 pDatBuffer + uStructDataOffset + iStructPointerSize, // 结构体之后的数据起始位置 dwDatBufferSize - uStructDataOffset - iStructPointerSize, // 剩余数据大小 &dwWriteSize, // 接收实际写入字节数 NULL); // 不使用重叠I/O if (dwWriteSize != dwDatBufferSize - uStructDataOffset - iStructPointerSize) // 如果写入字节数不匹配 { printf("大小不匹配\n"); goto ERROR_HANDLE; // 跳转到错误处理 } // 操作完成 CloseHandle(hFile); // 关闭文件句柄 return TRUE; // 返回成功 ERROR_HANDLE: printf("出错误了1\n"); if (hFile != INVALID_HANDLE_VALUE) // 如果文件句柄有效 { printf("出错误了\n"); CloseHandle(hFile); // 关闭文件句柄 } return FALSE; // 返回失败 } 这是一个组装exe文件的代码 修改代码添加随机区段随机大小 修改代码段减小熵值 不要改变原有意思