• 第 5 章 数组和广义表(数组的顺序存储结构实现)


    1. 背景说明

    数组一旦被定义,它的维数和维界就不再改变。因此,除了结构的初始化和销毁之外,数组只有存取元素和修改元素值的操作。

    2. 示例代码

    1) status.h

    1. /* DataStructure 预定义常量和类型头文件 */
    2. #include
    3. #ifndef STATUS_H
    4. #define STATUS_H
    5. #define NONE ""
    6. #define FILE_NAME(X) strrchr(X, '\\') ? strrchr(X,'\\') + 1 : X
    7. #define DEBUG
    8. #ifdef DEBUG
    9. #define CHECK_NULL(pointer) if (!(pointer)) { \
    10. printf("\nFileName: %-25s FuncName: %-20s Line: %-10d ErrorCode: %-3d\n", FILE_NAME(__FILE__), __func__, __LINE__, ERR_NULL_PTR); \
    11. return NULL; \
    12. }
    13. #else
    14. #define CHECK_NULL(pointer)
    15. #endif
    16. #ifdef DEBUG
    17. #define CHECK_VALUE(value, ERR_CODE) if (!(value)) { \
    18. printf("\nFileName: %-25s FuncName: %-20s Line: %-10d ErrorCode: %-3d\n", FILE_NAME(__FILE__), __func__, __LINE__, ERR_CODE); \
    19. return FALSE; \
    20. }
    21. #else
    22. #define CHECK_VALUE(value, ERR_CODE)
    23. #endif
    24. #ifdef DEBUG
    25. #define CHECK_RET(ret, FORMAT, ...) if (ret != RET_OK) { \
    26. printf("\nFileName: %-25s FuncName: %-20s Line: %-10d ErrorCode: %-3d" FORMAT "\n", FILE_NAME(__FILE__), __func__, __LINE__, ret, ##__VA_ARGS__); \
    27. return ret; \
    28. }
    29. #else
    30. #define CHECK_RET(ret, FORMAT, ...)
    31. #endif
    32. #ifdef DEBUG
    33. #define CHECK_CONDITION(condition, ERR_CODE, FORMAT, ...) if (condition) { \
    34. printf("\nFileName: %-25s FuncName: %-20s Line: %-10d ErrorCode: %-3d" FORMAT "\n", FILE_NAME(__FILE__), __func__, __LINE__, ERR_CODE, ##__VA_ARGS__); \
    35. return ERR_CODE; \
    36. }
    37. #else
    38. #define CHECK_CONDITION(condition, ERR_CODE, FORMAT, ...)
    39. #endif
    40. /* 函数结果状态码 */
    41. #define TRUE 1 /* 返回值为真 */
    42. #define FALSE 0 /* 返回值为假 */
    43. #define RET_OK 0 /* 返回值正确 */
    44. #define ERR_NULL_PTR 2 /* 空指针错误 */
    45. #define ERR_MEMORY_ACCESS 3 /* 访问内存错 */
    46. #define ERR_MEMORY_ALLOCATE 4 /* 内存分配错 */
    47. #define ERR_NULL_STACK 5 /* 栈元素为空 */
    48. #define ERR_PARA 6 /* 函数参数错 */
    49. #define ERR_OPEN_FILE 7 /* 打开文件错 */
    50. #define ERR_NULL_QUEUE 8 /* 队列为空错 */
    51. #define ERR_FULL_QUEUE 9 /* 队列为满错 */
    52. #define ERR_NOT_FOUND 10 /* 表项不存在 */
    53. typedef int Status; /* Status 是函数的类型,其值是函数结果状态代码,如 RET_OK 等 */
    54. typedef int Bollean; /* Boolean 是布尔类型,其值是 TRUE 或 FALSE */
    55. #endif // !STATUS_H

    2) sqArray.h

    1. /* 数组的顺序存储表示头文件 */
    2. #ifndef SQ_ARRAY_H
    3. #define SQ_ARRAY_H
    4. #include "status.h"
    5. #define MAX_ARRAY_DIM 10
    6. typedef int ElemType;
    7. typedef struct {
    8. ElemType *base;
    9. int dim;
    10. int *bounds;
    11. int *constants;
    12. } Array;
    13. Status InitArray(int dim, Array *array, ...);
    14. Status DestroyArray(Array *array);
    15. Status Locate(va_list ap, const Array *array, int *off);
    16. Status GetArrayValue(const Array *array, ElemType *e, ...);
    17. Status AssignArray(ElemType e, Array *array, ...);
    18. #endif // !SQ_ARRAY_H

    3) sqArray.c

    1. /* 数组的顺序存储实现源文件 */
    2. #include "sqArray.h"
    3. #include
    4. #include
    5. #include
    6. /*
    7. 前置条件:维数 dim 和各维长度合法
    8. 操作结果:构造相应的数组 *array,并返回 RET_OK
    9. */
    10. Status InitArray(int dim, Array *array, ...)
    11. {
    12. CHECK_CONDITION(!array, ERR_NULL_PTR, NONE);
    13. CHECK_CONDITION((dim < 1) || (dim > MAX_ARRAY_DIM), ERR_PARA, "dim = %d", dim);
    14. array->dim = dim;
    15. array->bounds = (int *)malloc(sizeof(int) * dim);
    16. CHECK_CONDITION(!(array->bounds), ERR_MEMORY_ALLOCATE, NONE);
    17. va_list ap;
    18. va_start(ap, array);
    19. int elemTotal = 1;
    20. for (int i = 0; i < dim; ++i) {
    21. array->bounds[i] = va_arg(ap, int);
    22. CHECK_CONDITION(array->bounds[i] < 0, ERR_PARA, "array->bounds[%d] = %d", i, array->bounds[i]);
    23. elemTotal *= array->bounds[i];
    24. }
    25. va_end(ap);
    26. array->base = (ElemType *)malloc(sizeof(ElemType) * elemTotal);
    27. CHECK_CONDITION(!(array->base), ERR_MEMORY_ALLOCATE, NONE);
    28. array->constants = (int *)malloc(sizeof(int) * dim);
    29. CHECK_CONDITION(!(array->constants), ERR_MEMORY_ALLOCATE, NONE);
    30. array->constants[dim - 1] = 1;
    31. for (int i = dim - 2; i >= 0; --i) {
    32. array->constants[i] = array->bounds[i + 1] * array->constants[i + 1];
    33. }
    34. return RET_OK;
    35. }
    36. /*
    37. 前置条件:数组 *array 已存在
    38. 操作结果:销毁数组 *array
    39. */
    40. Status DestroyArray(Array *array)
    41. {
    42. CHECK_CONDITION(!array, ERR_NULL_PTR, NONE);
    43. free(array->base);
    44. free(array->bounds);
    45. free(array->constants);
    46. array->base = array->bounds = array->constants = NULL;
    47. array->dim = 0;
    48. return RET_OK;
    49. }
    50. /*
    51. 前置条件:数组 *array 已存在,ap 指示的各下标值合法
    52. 操作结果:求出该元素在 *array 中的相对地址 *off
    53. */
    54. Status Locate(va_list ap, const Array *array, int *off)
    55. {
    56. CHECK_CONDITION(!array || !off, ERR_NULL_PTR, "array = %p, off = %p", array, off);
    57. int ind;
    58. *off = 0;
    59. for (int i = 0; i < array->dim; ++i) {
    60. ind = va_arg(ap, int);
    61. CHECK_CONDITION((ind < 0) || (ind >= array->bounds[i]), ERR_PARA, "ind = %d, array->bounds[%d] = %d",
    62. ind, i, array->bounds[i]);
    63. *off += (array->constants[i]) * ind;
    64. }
    65. return RET_OK;
    66. }
    67. /*
    68. 前置条件:数组 *array 已存在,各维度的数组的下标值合法
    69. 操作结果:将数组相应元素值赋值给 *e
    70. */
    71. Status GetArrayValue(const Array *array, ElemType *e, ...)
    72. {
    73. CHECK_CONDITION(!array || !e, ERR_NULL_PTR, "array = %p, e = %p", array, e);
    74. va_list ap;
    75. va_start(ap, e);
    76. int off;
    77. Status ret = Locate(ap, array, &off);
    78. CHECK_RET(ret, NONE);
    79. *e = *(array->base + off);
    80. return RET_OK;
    81. }
    82. /*
    83. 前置条件:数组 *array 已存在,各维度的数组的下标值合法
    84. 操作结果:将元素值 e 赋值给数组相应元素
    85. */
    86. Status AssignArray(ElemType e, Array *array, ...)
    87. {
    88. CHECK_CONDITION(!array, ERR_NULL_PTR, NONE);
    89. va_list ap;
    90. va_start(ap, array);
    91. int off;
    92. Status ret = Locate(ap, array, &off);
    93. CHECK_RET(ret, NONE);
    94. *(array->base + off) = e;
    95. return RET_OK;
    96. }

    4) main.c

    1. #include "sqArray.h"
    2. #include
    3. int main(void)
    4. {
    5. /* 数组 array[3][4][2] */
    6. Array array;
    7. int dim = 3, bound1 = 3, bound2 = 4, bound3 = 2;
    8. Status ret = InitArray(dim, &array, bound1, bound2, bound3);
    9. CHECK_RET(ret, NONE);
    10. int *p = array.bounds;
    11. for (int i = 0; i < dim; ++i) {
    12. printf("array.bound[%d] = %d ", i, *(p + i));
    13. }
    14. printf("\n");
    15. p = array.constants;
    16. for (int i = 0; i < dim; ++i) {
    17. printf("array.constants[%d] = %d ", i, *(p + i));
    18. }
    19. printf("\n\n%d pages %d row %d col element: \n", bound1, bound2, bound3);
    20. ElemType e;
    21. for (int i = 0; i < bound1; ++i) {
    22. for (int j = 0; j < bound2; ++j) {
    23. for (int k = 0; k < bound3; ++k) {
    24. ret = AssignArray(i * 100 + j * 10 + k, &array, i, j, k);
    25. ret |= GetArrayValue(&array, &e, i, j, k);
    26. CHECK_RET(ret, "i = %d, j = %d, k = %d", i, j, k);
    27. printf(" array[%d][%d][%d] = %3d", i, j, k, e);
    28. }
    29. printf("\n");
    30. }
    31. printf("\n");
    32. }
    33. ElemType *p1 = array.base;
    34. printf("array.base = \n");
    35. for (int i = 0; i < bound1 * bound2 * bound3; ++i) {
    36. printf("%22d", *(p1 + i));
    37. if (i % 2 == 1) {
    38. printf("\n");
    39. }
    40. }
    41. ret = DestroyArray(&array);
    42. CHECK_RET(ret, NONE);
    43. return 0;
    44. }

    3. 输出示例

  • 相关阅读:
    idea常用快捷键 idea搜索快捷键
    Zustand 和 React 上下文状态管理
    Vue插值表达式及常用指令
    注意这几种职场情况
    高级版的 jvisualvm :Spring Boot Admin 监控 Spring Boot 微服务项目
    走两步!AI通过步态诊断帕金森;从入门到如土·AI绘画中文指南;超好用的视频补帧软件;YOLO7人脸检测实现;前沿论文 | ShowMeAI资讯日报
    对map根据key值排序
    设计模式-04-原型模式
    如何同时打开两个pycharm文件
    【网络】HTTPS讲解(侧重于加密、秘钥、证书的讲解)
  • 原文地址:https://blog.csdn.net/qq_40613544/article/details/133759437