本章内容持续收录C语言的一些知识点

表达式必须是可以修改的左值

1
2
3
int a = 1;
int b = 2;
a + b = 3;

表达式 a + b 不是一个左值,因为它不能被修改。如果您尝试将 a + b 赋值为 3,则会收到一个编译错误,提示“表达式必须是可以修改的左值”。

指针与指向指针的指针

由于C语言的函数传值机制,修改值需要用指针。而修改指针就得用指向指针的指针(**)。—以单链表的初始化为例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
typedef struct LinkNode {
int data;
struct LinkNode* next;
}LinkNode,*LinkList;

void init(LinkNode** l) {
LinkNode* p = (LinkList)malloc(sizeof(LinkNode));
*l = p;
(*l)->data = 98;
(*l)->next = NULL;
}

int main(void) {
LinkNode* r;
init(&r);
printf("%d", r->data);
}

指针一般用于顺序存储结构,指向指针的指针一般用于链式存储结构。

对于链式结构还可以通过返回指针来构建。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>
#include <stdlib.h>

typedef struct LinkNode {
int data;
struct LinkNode* next;
} LinkNode, *LinkList;

LinkList init() {
LinkNode* p = (LinkList)malloc(sizeof(LinkNode)); // 动态分配内存
if (p == NULL) {
printf("Memory allocation failed!\n");
exit(1);
}
p->data = 3; // 初始化数据
p->next = NULL;
return p; // 返回头节点指针
}

int main(void) {
LinkList r = init(); // 初始化头节点
printf("%d\n", r->data); // 输出头节点的数据
free(r); // 释放动态分配的内存
return 0;
}

或者直接初始化传入的头结点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <stdlib.h>

typedef struct LinkNode {
int data;
struct LinkNode* next;
} LinkNode, *LinkList;

void init(LinkNode* l) {
l->data = 3; // 直接初始化传入的头节点
l->next = NULL;
}

int main(void) {
LinkNode r; // 定义一个头节点
init(&r); // 初始化头节点
printf("%d\n", r.data); // 输出头节点的数据
return 0;
}