Advanced Data Type

struct

record in pascal
program PrintBirthday;

type
    birthday = record
        year : integer;
        month : integer;
        day : integer;
    end;

var
    b : birthday;

begin
    b := (year: 2000; month: 1; day: 1); // 创建并初始化生日记录

    // 打印生日
    writeln('Birthday: ', b.day, '/', b.month, '/', b.year);
end.

struct in C
//* book.c -- one-book inventory */
#include <stdio.h>
#include <string.h>
char * s_gets(char * st, int n);
#define MAXTITL  41      /* maximum length of title + 1         */
#define MAXAUTL  31      /* maximum length of author's name + 1 */

struct book {            /* structure template: tag is book     */
    char title[MAXTITL];
    char author[MAXAUTL];
    float value;
};                       /* end of structure template           */

int main(void)
{
    struct book library; /* declare library as a book variable  */
    
    printf("Please enter the book title.\n");
    s_gets(library.title, MAXTITL); /* access to the title portion         */
    printf("Now enter the author.\n");
    s_gets(library.author, MAXAUTL);
    printf("Now enter the value.\n");
    scanf("%f", &library.value);
    printf("%s by %s: $%.2f\n",library.title,
           library.author, library.value);
    printf("%s: \"%s\" ($%.2f)\n", library.author,
           library.title, library.value);
    printf("Done.\n");
    
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');   // look for newline
        if (find)                  // if the address is not NULL,
            *find = '\0';          // place a null character there
        else
            while (getchar() != '\n')
                continue;          // dispose of rest of line
    }
    return ret_val;
}

(base) kimshan@MacBook-Pro output % ./"book"
Please enter the book title.
Hello
Now enter the author.
Charles
Now enter the value.
10
Hello by Charles: $10.00
Charles: "Hello" ($10.00)
Done.
struct 基础

声明

// 1
struct book {            /* structure template: tag is book     */
    char title[MAXTITL];
    char author[MAXAUTL];
    float value;
};                       /* end of structure template           */
struct book library, *p_lib;

// 2 简化
struct book { 
    char title[MAXTITL];
    char author[MAXAUTL];
    float value;
} library, *p_lib;

// 3. 数组
struct book library[MAXBOOKS];

// 4. 嵌套
struct book {
    char title[MAXTITL];
    char author[MAXAUTL];
    float value;
    struct book[MAXRELATE] res;
} library[MAXBOOKS];

// 5 typedef
typedef struct BiTNode
{
    int data;
    struct BiTNode *lchild;
    struct BiTNode *rchild;
    //struct BiTNode *parent; // 变成了 三叉链表
}BiTNode,*BiTree;

初始化

// 1. 按顺序
struct book library = 
{
    "The Pious Pirate and te Devious Damsel",
    "Rennee Vivotte",
    1.95
};

// 2. 按成员
struct book gift = 
{
    .value = 25.99;
    .author = "Me";
    .title = "You";
}

访问

scanf("%f", &library.value);
s_gets(library.author, MAXAUTL);

scanf("%f", &p_lib->value);
s_gets(p_lib->author, MAXAUTL);
struct + malloc

struct 中声明字符串然后 scanf 进来会导致错误(可能把字符串保存在任意位置)

#include <stdio.h>

#define LEN 20

struct names {
    char first[LEN];
    char last[LEN];
};

int main() {
    struct names veep = {"Talia", "Summers"};
    struct pnames treas = {"Brad", "Fallingjaw"};
    
    printf("%s and %s\n", veep.first, treas.first);
    
    struct names accountant;
    struct names attorney;

    printf("Enter the last name of your accountant: ");
    scanf("%s", accountant.last);

    printf("Enter the last name of your attorney: ");
    scanf("%s", attorney.last); /* 这里有一个潜在的危险 */
    
    return 0;
}

现在更好的办法是,struct 里边不要字符串,而是改成指针,每次去 malloc

// names3.c -- use pointers and malloc()
#include <stdio.h>
#include <string.h>   // for strcpy(), strlen()
#include <stdlib.h>   // for malloc(), free()
#define SLEN 81
struct namect {
    char * fname;  // using pointers
    char * lname;
    int letters;
};

void getinfo(struct namect *);        // allocates memory
void makeinfo(struct namect *);
void showinfo(const struct namect *);
void cleanup(struct namect *);        // free memory when done
char * s_gets(char * st, int n);

int main(void)
{
    struct namect person;
    
    getinfo(&person);
    makeinfo(&person);
    showinfo(&person);
    cleanup(&person);
    
    return 0;
}

void getinfo (struct namect * pst)
{
    char temp[SLEN];
    printf("Please enter your first name.\n");
    s_gets(temp, SLEN);
    // allocate memory to hold name
    pst->fname = (char *) malloc(strlen(temp) + 1);
    // copy name to allocated memory
    strcpy(pst->fname, temp);
    printf("Please enter your last name.\n");
    s_gets(temp, SLEN);
    pst->lname = (char *) malloc(strlen(temp) + 1);
    strcpy(pst->lname, temp);
}

void makeinfo (struct namect * pst)
{
    pst->letters = strlen(pst->fname) +
    strlen(pst->lname);
}

void showinfo (const struct namect * pst)
{
    printf("%s %s, your name contains %d letters.\n",
           pst->fname, pst->lname, pst->letters);
}

void cleanup(struct namect * pst)
{
    free(pst->fname);
    free(pst->lname);
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');   // look for newline
        if (find)                  // if the address is not NULL,
            *find = '\0';          // place a null character there
        else
            while (getchar() != '\n')
                continue;          // dispose of rest of line
    }
    return ret_val;
}


struct 复合字面量(C99)
/* complit.c -- compound literals */
#include <stdio.h>
#define MAXTITL  41
#define MAXAUTL  31

struct book {          // structure template: tag is book
    char title[MAXTITL];
    char author[MAXAUTL];
    float value;
};

int main(void)
{
    struct book readfirst;
    int score;
    
    printf("Enter test score: ");
    scanf("%d",&score);
    
    if(score >= 84)
        readfirst = (struct book) {"Crime and Punishment",
            "Fyodor Dostoyevsky",
            11.25};
    else
        readfirst = (struct book) {"Mr. Bouncy's Nice Hat",
            "Fred Winsome",
            5.99};
    printf("Your assigned reading:\n");
    printf("%s by %s: $%.2f\n",readfirst.title,
           readfirst.author, readfirst.value);
    
    return 0;
}
伸缩型成员变量(C99)

结构体里边的数组不写 MAX,只写 方括号,这样后边的 malloc 就要去计算大小了

// flexmemb.c -- flexible array member (C99 feature)
#include <stdio.h>
#include <stdlib.h>

struct flex
{
    size_t count;
    double average;
    double scores[];   // flexible array member
};

void showFlex(const struct flex * p);

int main(void)
{
    struct flex * pf1, *pf2;
    int n = 5;
    int i;
    int tot = 0;
    
    // allocate space for structure plus array
    pf1 = malloc(sizeof(struct flex) + n * sizeof(double));
    pf1->count = n;
    for (i = 0; i < n; i++)
    {
        pf1->scores[i] = 20.0 - i;
        tot += pf1->scores[i];
    }
    pf1->average = tot / n;
    showFlex(pf1);
    
    n = 9;
    tot = 0;
    pf2 = malloc(sizeof(struct flex) + n * sizeof(double));
    pf2->count = n;
    for (i = 0; i < n; i++)
    {
        pf2->scores[i] = 20.0 - i/2.0;
        tot += pf2->scores[i];
    }
    pf2->average = tot / n;
    showFlex(pf2);
    free(pf1);
    free(pf2);
    
    return 0;
}

void showFlex(const struct flex * p)
{
    int i;
    printf("Scores : ");
    for (i = 0; i < p->count; i++)
        printf("%g ", p->scores[i]);
    printf("\nAverage: %g\n", p->average);
}

匿名结构(C11)
struct person
{
    int id;
    struct {char first[20]; char last[20];}; // 匿名结构
};

// 初始化
struct person ted = {8483, {"ted", "grass"}};
结构体保存在文件中
#define MAXTITL 40  
#define MAXAUTL 40  
struct book {    
char title[MAXTITL];   
char author[ MAXAUTL ];    
float value;  
};  
  1. 可以用 fprintf
fprintf(pbooks, "%s. %s. %.2f\n", primer.title, primer.author, primer.value);
  1. fprintf + 固定宽度
fprintf(pbooks, "%39s%39s%8.2f\n", primer.title, primer.author, primer.value);
  1. 保存二进制文件

以二进制表示法储存数据的缺点是,不同的系统可能使用不同的二进制表示法,所以数据文件可能不具可移植性。甚至同一个系统,不同编译器设置也可能导致不同的二进制布局。

fwrite(&primer, sizeof(struct book),l,pbooks);  

union

只能存一个变量的数组,推荐使用方式:结构+联合

struct owner {
    char sosecurity[12];
    ...
};

struct leasecompany {
    char name[40];
    char headquarters[40];
    ...
};

union data {
    struct owner owncar;
    struct leasecompany leasecar;
};

struct car_data {
    char make[15];
    int status; /* 私有为0,租赁为1 */
    union data ownerinfo;
    ...
};


enum

枚举,默认值是从 0 开始的 int,也可以自定义数值

enum week = {Mon, Tus, Wen, Thr, Fri, Sat, Sun};
enum levels = {lows = 100, medium = 500, high = 2000};
Demo
/* enum.c -- uses enumerated values */
#include <stdio.h>
#include <string.h>    // for strcmp(), strchr()
#include <stdbool.h>   // C99 feature
char * s_gets(char * st, int n);

enum spectrum {red, orange, yellow, green, blue, violet};
const char * colors[] = {"red", "orange", "yellow",
    "green", "blue", "violet"};
#define LEN 30

int main(void)
{
    char choice[LEN];
    enum spectrum color;
    bool color_is_found = false;
    
    puts("Enter a color (empty line to quit):");
    while (s_gets(choice, LEN) != NULL && choice[0] != '\0')
    {
        for (color = red; color <= violet; color++)
        {
            if (strcmp(choice, colors[color]) == 0)
            {
                color_is_found = true;
                break;
            }
        }
        if (color_is_found)
            switch(color)
        {
            case red    : puts("Roses are red.");
                break;
            case orange : puts("Poppies are orange.");
                break;
            case yellow : puts("Sunflowers are yellow.");
                break;
            case green  : puts("Grass is green.");
                break;
            case blue   : puts("Bluebells are blue.");
                break;
            case violet : puts("Violets are violet.");
                break;
        }
        else
            printf("I don't know about the color %s.\n", choice);
        color_is_found = false;
        puts("Next color, please (empty line to quit):");
    }
    puts("Goodbye!");
    
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');   // look for newline
        if (find)                  // if the address is not NULL,
            *find = '\0';          // place a null character there
        else
            while (getchar() != '\n')
                continue;          // dispose of rest of line
    }
    return ret_val;
}



typedef

typedef 是编译器解释的,#define 是预处理器解释的。

typedef+结构(上边结构里边)


复杂声明

int a[2][3];

eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nO1daVPbSFx1MDAxM/6eX5Fiv20t2pnuOfdcdTAwMWKQhDtcdTAwMWMmXHUwMDA0SG1RPuQjXHUwMDE4yfjAkK3897dHgCXLyFx1MDAxOONDm32dXHUwMDE0wVx1MDAxYdlcdTAwMWFp+ul+numeyT/v3r9f6d63/JW/3q/4d+Vis1FpXHUwMDE3+yt/uOO3frvTXGJcdTAwMDNqguh9J+y1y9GZ9W631fnrzz+LrZZXa3RLYXjllcPrh4/5Tf/aXHUwMDBmulx1MDAxZDrxXHUwMDFivX///p/oZ+JCXf+uXHUwMDFinVx1MDAxYlx1MDAxZI0vIyB98HNcdTAwMThEV1x1MDAwNFx1MDAwZUZcdTAwMTijtFx1MDAxZZzR6HygK3X9XG41V4vNjlx1MDAxZre4QytcdTAwMDdnbNdf3127qTbOt897R7vhvqnHV602ms1C975cdTAwMTl1qFx1MDAxM9J9x22dbju88r82Kt36080njmd9qlx1MDAxZPZq9cDvuFx1MDAxYueDo2GrWG50790xxlx1MDAwNkeLQS36jvjIXHUwMDFkvZOIXHUwMDFlXHUwMDEzkjNhXHJcdTAwMTPKmEGr+zyA9Fx1MDAwMFBcdTAwMThcdTAwMDYgXHUwMDE0s2hSXHUwMDFk21xim2Hbdew3qFpfiLhrpWL5qkb9XHUwMDBiKoNzuu1i0GlcdTAwMTXbNFLxef3HWzbMXHUwMDEz1lplhVx1MDAwMVx1MDAwMTzRkbrfqNW7rjcyvrpcdTAwMWZcclx1MDAwMufSSNTW2EGLu2Zru1x1MDAxMpnC3/Gjb1x1MDAxN6/9bfeRoNdsJp9fUHl8fkNcciXX8DFtVUnLSlxmO7DguH1S7vnl80rtZLe4gbeVtcFcdTAwMWRcdTAwMGWZYbHdXHUwMDBl+yuDlp9/jPtee79cdTAwMTP8uLztfb6rfvix1S/37+qXm5N97+Nv8Vx1MDAwM+i1KsVcdTAwMDfD5Vx1MDAxYaTkQqJUOn7IzUZwlX5cYs2wfPWMrVfDoFto/IgwwoaOfipeN5r3Q7ZcdTAwMTjhznXwXHUwMDFi+5v+rlxmNaw1XHUwMDFiNVx1MDAwN8KVpl9cdTAwMWRGZ7dBfmHQ3FxyW3FrmS5UbFx1MDAwNH57dDjDdqPWXGKKzZOsi9Jd+ltP5sS9hEGVilx1MDAxZN+1uuPmXWJsJvYkXG6zPFx0l1pcdEveJD7jRU+y8VFcdTAwMTe+dM+PVeNMNaty26+Iu3x7XHUwMDEyJSUhXHUwMDE4XHUwMDE0XHUwMDE3OuUqXHUwMDFlPFx09yzTXHUwMDEyuUZcdTAwMDOGJ7Gc8iTcd3+m9yRcdTAwMWE8Lq3VyFx1MDAwNVl58kpjPFx0cJTk7lx1MDAwNcTefk6eZFxmJlx1MDAxMVx1MDAwNLcsaa3zxyRfXHUwMDA2JvmiMKnTXHUwMDA3XHUwMDA3mFQg0VxuXHUwMDE08WN5XHSTPdPf2j2wm3BY3lhjd9qorl/KNya1Up5cdTAwMDXGOJJha1x1MDAxNGJcdTAwMTiT3HrzgyFcdTAwMDV0qymgS2D0k9n42uNcdTAwMDK6XHUwMDA0Llxmar5UXHUwMDE4XG4mUSRccnT+MIRlwFx1MDAxMFx1MDAxNlx1MDAwNEOO2bHROtJJTnry2Li69/nm6nj9+0Et9I8uzqTof7jdyDdcdTAwMGWJbHlEr41gzGhjmVx1MDAxYcahJlx1MDAwZW6JYFx1MDAxYoqemlx1MDAxYp2z2GiFpiFiXHUwMDE4NyxcdTAwMDOTgnGZtNY5Y5Ivg67yxdFVXHUwMDBlKn30XHSTXHUwMDE2gYRcdTAwMTWpwokhefxlY6cusXZ8sFx1MDAxZaizQnntoFn5nG9IKqk91IpYXHUwMDFmQ1x1MDAwMFCjkFx1MDAwNGUl4VFpqVxyT/VrdohU6Fx1MDAxOU6IVIYpJZiaXGaSim5QKmCx11xcXHUwMDA2JKVNiJ6FQHLxbJUvjq1yZOmjT5Aknmo542ZytopH1/Wdxu1p40dHXHUwMDFkfy3ip+JcdTAwMGb8nm9IXHUwMDEyXHUwMDA2KEqilkpzNErHV36AJPOMM3nGwIJVNtWvmVx1MDAwNkmFxFmN0cA0w/huxjFXxVx1MDAxNFx1MDAxYYmwXFxIWs100ljnXHUwMDBmycUzV75I5mrSR1x1MDAwN8xcdTAwMTWIzVmcnLd+2OqvXHUwMDFktFum/uP7fqhEsFe+uT/PN1wi0VxiT1x1MDAxM1FUXHUwMDFjh+dsXCJAXG7jUciS1GBNNKczN0RcbuZp0pJyXHUwMDE0++NcdTAwMTBpkFgr8KVcdTAwMDJSK2tcdTAwMTYnJZthrVFeLFx1MDAxY1OXnFx1MDAwNVx1MDAxONt+uftgj88gUmXSVlx1MDAwZVx1MDAwNohcdTAwMTW9XCJG+vJo6/uhOL/Zrq7LvZ2i2TJfTL5cdTAwMTEpgXnWkFwiI9uSUiSQ8DCjXHUwMDAznkGpyC1Ji+N0pNW8XGbTXHUwMDAzXHUwMDEy0Xho0FxuriTDpKBcdTAwMWRcdTAwMDCSzlx1MDAwMLQuOZOe71x1MDAxZEz1XHUwMDE4qaXRM5jqiZMnT0aEj0d+xrf4mpRcdTAwMGWunVx1MDAxZV6FXHUwMDA3Vbw8XHUwMDBlLy3Uzj6p2uWsUi9O50uehMxcdTAwMGJOYXq08IRmXHUwMDFlmXlhhpN/4pPjZbdSL4D5umtP5fZcdTAwMDUvNa93YD3MOV649UjqWfLE9OyNTOGF1Fx1MDAxN4UwXHUwMDEwUjFcdTAwMDLTPGdeZoBcdTAwMTgjmFF2JvMwU1x1MDAwMWZcXJwjf6Jek02cR1x1MDAwMEBUykhiXGJcdTAwMTNcdTAwMWJ01Vx1MDAwNpunm+t8tVx1MDAwNIdlXHUwMDBiXHUwMDA129rdhLxcdTAwMWI0etwq7abzk1x1MDAxZT4yZ4ZcdTAwMWVcIjfCjEzvpc3ZJ1mD/Fxy5iyVp8HSJaxW8tlZXHUwMDBizqzHXHUwMDFmlNzwnObjXHUwMDE0XHUwMDA2Q+ojmmW5/3FcdTAwMGVakzeYmYPOnoHLlPtuXGKNYcn5nZdMuXwob/3bw/omK8tbu7d2vNsuqXybMrlDT1i0pOxcdTAwMTkncs+HjJmswyPyzjRqZPP1zST4Lb1cdTAwMDA1i+LARPJcdTAwMDJRaNJGapmz4i7PvsBMVat+33GiYbFcbmP0qvNU/MCzUWlcdTAwMTHQWGYnXHUwMDBmMEFcdTAwMDW2vnzyYfND76T3/XS/v31/8DHfqJQgPFx1MDAwMIpcdTAwMWZKXHUwMDFizZN521x1MDAwN1RqwlxuKWuQipRGonVcdTAwMGX549dcdTAwMTeEXHUwMDE5XHUwMDAwlMjUMtPHXHUwMDBiXHUwMDA25a9fWVx1MDAwNYmnmYakJipNdEhOXHUwMDBlyVp4eoLYgk6xf/Lpols1e81cdTAwMGY635BUQnlEoqxSUsJIXHUwMDE5XHUwMDA3vfdIUrqyXHUwMDA1Q4whf6VVzCUutOBzL9LMXHUwMDE5KH/p0ipcdTAwMTgzM64tKEuSe/JcdTAwMDRyx7bPd8PSiazfXHUwMDFk9XD78624rLfzXHJKLY1HVFx1MDAwMJWEUSWGXHUwMDAyPNDCslRbPoqsjJRcdTAwMTYkuc7/XHUwMDE4IH/pXCIrXHUwMDEyL5mAJE5kiEK9grjWXHUwMDBim+3SXHUwMDBmvnt+f9a6Kn/xNy57Z2v5XHUwMDA2pLHCc4xcdTAwMTVBc2FEqlx1MDAwMJmioyOuXFzRaeOnRpZcdTAwMTIkudKgyFn8p4jrr15jhWPWXHUwMDA0WK2QI06OSN/cXWz011fb1cvq4f7qx83Cxl7O5yo548pcdTAwMTOCjItcdTAwMTFDJ1pcdTAwMTBb91x1MDAwMyS5x7Uku1x1MDAxN5JzzedX0TFdkZX7hKVuL7WkY1x1MDAxOaD8pauscMyiXHUwMDAwoVx1MDAxNFxuK/XkqNTfT2onX497Slx1MDAxZV/Dbr3S2+jeXHUwMDFk5Vx1MDAxY5VcdTAwMWO0Z1x1MDAxY0G3j5JxXHUwMDE4lWg8rbRGpjlcZtUq56POXG5olFx1MDAxMND+h+Zdf506q/HJashcXIwrXHUwMDE1KGmsmXwt7teD+1PJOltEfa/CU9XQ0Eo+plx1MDAxOVx1MDAwMLNS7NT9XHUwMDE55/YoID5VXHUwMDFjp6qtyN6IvzKrlLbzTYZw6TJ7XHUwMDE0rIm+XGZVdVxyUElxm6K1pl6kk39PIEWthYJkvWp+knuvxe5Yg47M/rkow7NMmUvyucKAnTy3p1n9y9ZFv3Zx++lroXp9s7u3XHUwMDEz8nxcdTAwMDdcdTAwMTnlolxil2Qh0cKzkdWggvyHpvgj9XxnLNmo9YL0KLZRmOfpxTZPhUlIfy2IXHUwMDE50L5R44U3XHUwMDE5ryBcdTAwMDYrp1pcdTAwMDbT6Vx1MDAxNtvd9UZQaVx1MDAwNLX0R/ygktHSLHa6XHUwMDFi4fV1o0vdOFxmXHUwMDFiQTd9RvS9a65cdTAwMDaq7lx1MDAxN0eeXHUwMDA1fXNmW8t93XAlVvzb+3jkojeD3//+4+Wz0yNcdTAwMWN/+F3y39diOiFQ0uHJclx1MDAxYVx1MDAxY1x1MDAwYpND+mqHXHUwMDA3VenbcK+sal8+XHUwMDE2Oripcp6u18J4XHUwMDAwkkvijtyJqGFIk9RTQFZqkDE911x1MDAwNd7MXHUwMDEz2jBjMFpK95yWQyRh+VRV8Ex4Ypa7iqVZbFx1MDAxYjFzhGueTF/+XHUwMDFm4U+v1axhd6/UgM9cbvCZ0zdWMbTIXlx1MDAxMcPLXHUwMDE3XHUwMDA3+5tHnavvXHUwMDA3bXV9eYNH/updIf+A1yCsjlxuJ0eKzdxqXHUwMDFkbYWUMj2nMnvAg5FcdTAwMDa0wlQpWVx1MDAxY9ONx1x1MDAxODAuuGL8OUZKwp5cdTAwMDFKlceYTvxITrXrwy+O+Kxhd6+RXHUwMDAxn1x1MDAxMeQzk5pCXHQk/akmR3xwtVM/xHrzY3BSrm3fVLSoXeW90IBYuys91CpcdTAwMTU4XHUwMDFmXHUwMDAwr1116TP6dFxuvP9WgiqUSlx1MDAxM1x1MDAxMXZcdTAwMDRiXHUwMDE2br0rT6daXHUwMDFmwa2l4Vx1MDAwZUNzUZtvXHUwMDA1t5H8/+B+4eyRXHUwMDExfiWaXHUwMDFm1mA8XHUwMDAzZ1x1MDAxYYFMQLvNilx1MDAwMMzkgFx1MDAxZb/PVy5cdTAwMDFN5ueRlEUk3zVaLu7mgd2+R4hE3Fx1MDAxNfH6TERPsLtbJqIl+XHG7DNeZYBw5lx1MDAxOWs5aVsghy5cdTAwMTFFYp+5x1wiXCKjXHUwMDA1+Z08MnaX67XxkE5cdTAwMGbxRMdcdTAwMWU3NIxuZKVcdTAwMDWNM9MubFx1MDAxNjYvSvv7XHUwMDFjPq+VXHUwMDBmYpbkbjos9zrRY4z0rpKaXHUwMDFlolFMyUTMXFypXHUwMDE1W85cIjwjwTo69MDpRm59yLdkdWn8TodDXTJcdTAwMTQrXHUwMDEwjJOGXHUwMDEyVEypXHUwMDEzPVx1MDAxMpJr4zZhSFx1MDAwNPK4QzN2aWlnMVOvlmnr7rU6auav9HOZxVgye7pRS05q5TVLXHTG21s+/Vx1MDAxY1pPkj0/ZZLS1IWjJ5lgcqBcdTAwMWXn4ulIhbqMsUktV1x1MDAxOJfNwlxiXHUwMDE0XFzOve5jYGmz3cDyyWzHuEfS7K9a7Vx1MDAxON/zNLmy338vLjZPNnTBWeTIMslcZumgTJS7pVRailegfPzuovlEuVx1MDAxNp7LOTHhcoGjfEZcdM9GS+65iyQ68TCmWP+ciXJhSZdyzVx1MDAxODrpObQvVrz2XHI86oTTJSRdtVx1MDAxNolFzoNcIkzyXHUwMDEzLv+RQ9FcdTAwMTJcdTAwMTGDqSA7IaPZvLrtb1x1MDAxN/p7N/efPt/Ug1B/XHJ7xefpXHUwMDAz6Vx1MDAwMZCWRl5cbk1cdTAwMWWejTJcdTAwMWH0NNFbhJH5/nlxXHUwMDFhiuNMMWFcXFrLus2RpeUjvbJcdTAwMWU39DDTiubfSWuyTd69VketfUa8hlRLlscjYyCAv8bhjTe6fDo8oT0kOm/wMeWScnhcdTAwMTKIzSNcdTAwMTdW8Fx1MDAxN2Zg3+DvXHUwMDAwPUVcdTAwMWHHXHUwMDE4ethcdTAwMTgtMJmI2ZCbtpZOXyqzme9cdTAwMTbaU7vJ6ZjNoonNjHlN5ia9mVtUSHI60dZcZlx1MDAxM2NcXFx1MDAwNXubh6WgXHUwMDFjXGJcdTAwMTFcdTAwMTR06fRgX1x1MDAxZeZ8zpV8nEdcbkBcdLcqQ+pUNVx1MDAxZck3j3MjlIWX9s1+65J+Q/LUlePJ9CqycShcdTAwMTfacq2MWupcdTAwMDb8+dqt5W0oL36Dv7/hwmv9Ulx1MDAxN52rjslezunmIEG9XCKrOn7kc4l3XG7WRGqlqzKybmXzcFx1MDAxOVx1MDAwNTfKY1xiT2VTY+r83lxud6JcdTAwMTbCkGVzSG+vXHUwMDEwq1x1MDAxOEN6SnGlKJA/WynlRFxm3fEsNs2ftYaZXHUwMDFltlx1MDAxM2qY8aFmWC7QOGv3P8lcYlTIXHUwMDE4s4mzXHUwMDFl1Fx1MDAwMidha9wqLcNccr5hXnb8jmbDnUJccqhobFx1MDAxNYlcdTAwMTm65minNJHLwVZiI/35V+mXLFt3r7SVx1/2LvmvXHUwMDBiXHUwMDE10devXHUwMDE0W61Cl6xtMFx1MDAwZWT1jcqjp4/vceW24ffXx6Py3eNcdTAwMTN1nsqPYPDz3c//XHUwMDAx4eLb3yJ9 a[0][0]a[0][1]a[0][2]a[1][0]a[1][1]a[1][2]logicphysicala[0][0]a[0][1]a[0][2]a[1][0]a[1][1]a[1][2]**a*aa[2][3]

int *p[10]; // 含有十个指针的数组
int (*p)[10]; // 指向含有十个整数的数组的指针
// 含有4 个指针的数组
    int *p[4];
    p[0] = &a[0][0];
    p[1] = &a[0][1];
    p[2] = &a[1][0];
    p[3] = &a[1][1];
    printf("%p %p %p %p\n", p[0], p[1], p[2], p[3]);
    printf("%d %d %d %d\n", *p[0], *p[1], *p[2], *p[3]);
    // 0x7ff7ba96b810 0x7ff7ba96b814 0x7ff7ba96b81c 0x7ff7ba96b820
    // 11 12 21 22

    // 指向数组的指针
    int num[4] = {100, 200, 300, 400};
    int(*q)[4] = num;
    printf("%p, sizeof(int)=%u,sizeof(q)=%u, sizeof(*q)=%u\n", q, sizeof(int), sizeof(q), sizeof(*q));
    printf("%d %d %d %d\n", (*q)[0], (*q)[1], (*q)[2], (*q)[3]);
    // 0x7ff7be28a7e0, sizeof(int)=4,sizeof(q)=8, sizeof(*q)=16
    // 100 200 300 400