• Linux 链表示例 LIST_INIT LIST_INSERT_HEAD


    list(3) — Linux manual page

    用Visual Studio 2022创建CMake项目

    * CmakeLists.txt

    1. # CMakeList.txt : Top-level CMake project file, do global configuration
    2. # and include sub-projects here.
    3. #
    4. cmake_minimum_required (VERSION 3.12)
    5. project ("llist")
    6. # Include sub-projects.
    7. add_subdirectory ("llist")

    * llist/CMakeLists.txt

    1. # CMakeList.txt : CMake project for llist, include source and define
    2. # project specific logic here.
    3. #
    4. cmake_minimum_required (VERSION 3.12)
    5. # Add source to this project's executable.
    6. add_executable (llist "llist.c" "llist.h")
    7. if (CMAKE_VERSION VERSION_GREATER 3.12)
    8. set_property(TARGET llist PROPERTY CXX_STANDARD 11)
    9. endif()
    10. # TODO: Add tests and install targets if needed.

    * llist/llist.h

    1. // llist.h : Include file for standard system include files,
    2. // or project specific include files.
    3. #pragma once
    4. #ifndef NULL
    5. #define NULL (void *)0
    6. #endif
    7. /*
    8. * List definitions.
    9. */
    10. #define LIST_HEAD(name, type) \
    11. struct name { \
    12. struct type *lh_first; /* first element */ \
    13. }
    14. #define LIST_HEAD_INITIALIZER(head) \
    15. { NULL }
    16. #define LIST_ENTRY(type) \
    17. struct { \
    18. struct type *le_next; /* next element */ \
    19. struct type **le_prev; /* address of previous next element */ \
    20. }
    21. /*
    22. * List functions.
    23. */
    24. #define LIST_INIT(head) do { \
    25. (head)->lh_first = NULL; \
    26. } while (/*CONSTCOND*/0)
    27. #define LIST_INSERT_AFTER(listelm, elm, field) do { \
    28. if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
    29. (listelm)->field.le_next->field.le_prev = \
    30. &(elm)->field.le_next; \
    31. (listelm)->field.le_next = (elm); \
    32. (elm)->field.le_prev = &(listelm)->field.le_next; \
    33. } while (/*CONSTCOND*/0)
    34. #define LIST_INSERT_BEFORE(listelm, elm, field) do { \
    35. (elm)->field.le_prev = (listelm)->field.le_prev; \
    36. (elm)->field.le_next = (listelm); \
    37. *(listelm)->field.le_prev = (elm); \
    38. (listelm)->field.le_prev = &(elm)->field.le_next; \
    39. } while (/*CONSTCOND*/0)
    40. #define LIST_INSERT_HEAD(head, elm, field) do { \
    41. if (((elm)->field.le_next = (head)->lh_first) != NULL) \
    42. (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
    43. (head)->lh_first = (elm); \
    44. (elm)->field.le_prev = &(head)->lh_first; \
    45. } while (/*CONSTCOND*/0)
    46. #define LIST_REMOVE(elm, field) do { \
    47. if ((elm)->field.le_next != NULL) \
    48. (elm)->field.le_next->field.le_prev = \
    49. (elm)->field.le_prev; \
    50. *(elm)->field.le_prev = (elm)->field.le_next; \
    51. } while (/*CONSTCOND*/0)
    52. #define LIST_FOREACH(var, head, field) \
    53. for ((var) = ((head)->lh_first); \
    54. (var); \
    55. (var) = ((var)->field.le_next))
    56. /*
    57. * List access methods.
    58. */
    59. #define LIST_EMPTY(head) ((head)->lh_first == NULL)
    60. #define LIST_FIRST(head) ((head)->lh_first)
    61. #define LIST_NEXT(elm, field) ((elm)->field.le_next)
    62. // TODO: Reference additional headers your program requires here.

    llist/llist.c

    1. /* llist.c : Defines the entry point for the application.* /
    2. /* #include */
    3. #include
    4. #include /* malloc, free */
    5. #include /* strcpy */
    6. #include "llist.h"
    7. struct entry {
    8. char s[256];
    9. LIST_ENTRY(entry) entries;
    10. };
    11. LIST_HEAD(listhead, entry);
    12. int main()
    13. {
    14. struct listhead head;
    15. struct entry* n1, * n2, * np;
    16. /* Initialize the list */
    17. LIST_INIT(&head);
    18. /* Insert at the head */
    19. n1 = malloc(sizeof(struct entry));
    20. strcpy_s(n1->s, 256, "line#1");
    21. LIST_INSERT_HEAD(&head, n1, entries);
    22. /* Insert after */
    23. n2 = malloc(sizeof(struct entry));
    24. strcpy_s(n2->s, 256, "line#2");
    25. LIST_INSERT_AFTER(n1, n2, entries);
    26. struct entry* n3;
    27. n3 = malloc(sizeof(struct entry));
    28. strcpy_s(n3->s, 256, "line#3");
    29. LIST_INSERT_BEFORE(n2, n3, entries);
    30. LIST_FOREACH(np, &head, entries) {
    31. printf("%s\n", np->s);
    32. }
    33. LIST_REMOVE(n2, entries);
    34. free(n2);
    35. LIST_FOREACH(np, &head, entries) {
    36. printf("%s\n", np->s);
    37. }
    38. /* Destroy */
    39. while (LIST_FIRST(&head) != NULL) {
    40. LIST_REMOVE(LIST_FIRST(&head), entries);
    41. free(LIST_FIRST(&head));
    42. }
    43. return 0;
    44. }

    选择最外层的CMakeLists.txt 右键Build

    CMakePresets.json

    1. {
    2. "version": 3,
    3. "configurePresets": [
    4. {
    5. "name": "windows-base",
    6. "hidden": true,
    7. "generator": "Ninja",
    8. "binaryDir": "${sourceDir}/out/build/${presetName}",
    9. "installDir": "${sourceDir}/out/install/${presetName}",
    10. "cacheVariables": {
    11. "CMAKE_C_COMPILER": "cl.exe",
    12. "CMAKE_CXX_COMPILER": "cl.exe"
    13. },
    14. "condition": {
    15. "type": "equals",
    16. "lhs": "${hostSystemName}",
    17. "rhs": "Windows"
    18. }
    19. },
    20. {
    21. "name": "x64-debug",
    22. "displayName": "x64 Debug",
    23. "inherits": "windows-base",
    24. "architecture": {
    25. "value": "x64",
    26. "strategy": "external"
    27. },
    28. "cacheVariables": {
    29. "CMAKE_BUILD_TYPE": "Debug"
    30. }
    31. },
    32. {
    33. "name": "x64-release",
    34. "displayName": "x64 Release",
    35. "inherits": "x64-debug",
    36. "cacheVariables": {
    37. "CMAKE_BUILD_TYPE": "Release"
    38. }
    39. },
    40. {
    41. "name": "x86-debug",
    42. "displayName": "x86 Debug",
    43. "inherits": "windows-base",
    44. "architecture": {
    45. "value": "x86",
    46. "strategy": "external"
    47. },
    48. "cacheVariables": {
    49. "CMAKE_BUILD_TYPE": "Debug"
    50. }
    51. },
    52. {
    53. "name": "x86-release",
    54. "displayName": "x86 Release",
    55. "inherits": "x86-debug",
    56. "cacheVariables": {
    57. "CMAKE_BUILD_TYPE": "Release"
    58. }
    59. },
    60. {
    61. "name": "linux-debug",
    62. "displayName": "Linux Debug",
    63. "generator": "Ninja",
    64. "binaryDir": "${sourceDir}/out/build/${presetName}",
    65. "installDir": "${sourceDir}/out/install/${presetName}",
    66. "cacheVariables": {
    67. "CMAKE_BUILD_TYPE": "Debug"
    68. },
    69. "condition": {
    70. "type": "equals",
    71. "lhs": "${hostSystemName}",
    72. "rhs": "Linux"
    73. },
    74. "vendor": {
    75. "microsoft.com/VisualStudioRemoteSettings/CMake/1.0": {
    76. "sourceDir": "$env{HOME}/.vs/$ms{projectDirName}"
    77. }
    78. }
    79. },
    80. {
    81. "name": "macos-debug",
    82. "displayName": "macOS Debug",
    83. "generator": "Ninja",
    84. "binaryDir": "${sourceDir}/out/build/${presetName}",
    85. "installDir": "${sourceDir}/out/install/${presetName}",
    86. "cacheVariables": {
    87. "CMAKE_BUILD_TYPE": "Debug"
    88. },
    89. "condition": {
    90. "type": "equals",
    91. "lhs": "${hostSystemName}",
    92. "rhs": "Darwin"
    93. },
    94. "vendor": {
    95. "microsoft.com/VisualStudioRemoteSettings/CMake/1.0": {
    96. "sourceDir": "$env{HOME}/.vs/$ms{projectDirName}"
    97. }
    98. }
    99. }
    100. ]
    101. }

    See also: SysTutorials LIST_INSERT_AFTER (3) - Linux Manuals

    Linked Lists in the Linux Kernel - An example in userspace

    Doubly linked list​​​​​​​ 

  • 相关阅读:
    [NOIP2012 提高组] Vigenère 密码
    【毕业设计】基于单片机的智能温控农业大棚系统 - 物联网 stm32
    MyBatisPlue-03
    MFC的CPen与CBush画图对象使用步骤
    Electron程序逆向(asar归档解包)
    使用Resnet网络对人脸图像分类识别出男女性别(包含数据集制作+训练+测试)
    此页面不能正确地重定向
    缓存(cache)与缓冲区(buffer)的主要区别
    转载 | 自动驾驶开源数据集总结
    Python---类型注解
  • 原文地址:https://blog.csdn.net/fareast_mzh/article/details/133205401