知识点预习
指针的概念
#include <stdio.h>
int main()
{
int a = 5, b = 9;
int *p = &a; // (int *) p=&a 只有初始化时需要加*,赋值不需要
printf("a = %d\n", a);
printf("p = %d\n", *p);
p = &b; // 取b的地址赋值给p,直接赋值
printf("b = %d\n", b);
printf("p = %d\n", *p);
int num[105] = {9, 8, 7}; // num <=>&num[0]
int *q = num;
q[1] = 100;
printf("%d %d %d\n", num[0], num[1], num[2]);
printf("num size=%lu,a size=%lu\n", sizeof(num), sizeof(a)); // sizeof 长度
printf("a->%p\nb->%p\np->%p\nnum->%p\nq->%p\n", &a, &b, p, num, q); // &a 取a地址
return 0;
}
- 输出
$ gcc point.c
$ ./a.out
a = 5
p = 5
b = 9
p = 9
9 100 7
num size=420,a size=4
a->0x7ffeeed7a898
b->0x7ffeeed7a894
p->0x7ffeeed7a894
num->0x7ffeeed7a8a0
q->0x7ffeeed7a8a0
结构体
#include <stdio.h>
typedef struct node // 类型struct 名node
{
int x, y;
} node; // 启别名 typedef...{...}node
int main()
{
node a;
a.x = 5; //普通变量".""
a.y = 20;
printf("a.x = %d,a.y = %d\n", a.x, a.y);
node *p = &a; // 指针使用"->"
p->x = 9;
p->y = 100;
printf("a.x = %d,a.y = %d\n", a.x, p->y);
return 0;
}
输出
$ gcc typestruct.c
$ ./a.out
a.x = 5,a.y = 20
a.x = 9,a.y = 100
动态类型分配
malloc
定义于头文件 <stdlib.h>
void* malloc( size_t size );
分配 size
字节的未初始化内存。
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *num = (int *)malloc(100000 * sizeof(int));
// 定义一个int型的指针num
// (int *) 强制类型转换
// 100000 * sizeof(int) 申请了一个100000个int空间大小的空间
num[0] = 123;
num[99999] = 12345;
printf("%d %d %d\n", num[0], num[99999], num[12000]);
free(num); // 释放申请空间,虽然可以访问,但是是一个危险操作
num = NULL; // 设置值
return 0;
}
输出
$ gcc malloc.c
$ ./a.out
123 12345 0
线性表
线性表的顺序存储又叫做顺序表,它是由一组地址连续的存储单元依次存储线性表中的数据元素,从而使得逻辑上相邻的两个元素,在物理位置上也相邻。(大家可以先简单的理解成数组)
插入新值
删除值
/**
* @file lintable.c
* @author your name (you@domain.com)
* @brief
* @version 0.1
* @date 2022-04-15
*
* @copyright Copyright (c) 2022
* 顺序表
*/
#include <stdio.h>
#include <stdlib.h> // 为了动态内存分配
typedef struct vector
{
int *data;
int size, cap; // size 已经存储的变量个数 cap 容量上线
} vector;
// 结构初始化
vector *init(int cnt)
{
vector *p = (vector *)malloc(sizeof(vector)); // 申请顺序表空间
p->data = (int *)malloc(sizeof(int) * cnt); // 申请顺序表存储数据空间
p->size = 0;
p->cap = cnt;
return p;
}
// 销毁
void delete_vector(vector *p)
{
// 先销毁
free(p->data);
free(p);
}
void show_vector(vector *v)
{
printf("----size-%d,cap-%d-----\n", v->size, v->cap);
for (int i = 0; i < v->size; i++)
{
printf("%d ", v->data[i]);
}
printf("\n-----------\n");
}
// 在下标ind 插入val。 1 失败,0 成功
int insert_ele(vector *v, int ind, int val)
{
if (ind > v->size)
{
return 1; // 插入失败,无法跳跃插入
}
if (v->size == v->cap)
{
v->cap *= 2; // 扩容为原来的2倍
v->data = (int *)realloc(v->data, sizeof(int) * v->cap); // 新的空间指针赋值老数据
}
for (int i = v->size; i > ind; i--)
{
v->data[i] = v->data[i - 1]; // 元素依次后移,空出插入元素位置
}
v->data[ind] = val; // 插入元素
v->size++; // 插入数量+1
return 0;
}
// 删除
int delete_ele(vector *v, int ind)
{
if (ind < 0) // 下标不合法
{
return 1;
}
if (v->size <= ind) // 删除元素不存在
{
return 1;
}
for (int i = ind; i < v->size - 1; i++)
{
v->data[i] = v->data[i + 1]; // 将后面的元素向前移动
}
v->size--; // 元素数量-1
return 0;
}
int main()
{
int n, cnt;
scanf("%d%d", &n, &cnt);
vector *v = init(cnt);
for (int i = 0; i < n; i++)
{
int a, b;
scanf("%d", &a);
if (a == 0)
{
scanf("%d%d", &a, &b);
insert_ele(v, a, b);
}
else if (a == 1)
{
scanf("%d", &a);
delete_ele(v, a);
}
show_vector(v);
}
delete_vector(v);
v = NULL;
return 0;
}
链表
链表的插入
链表的删除
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node *next;
} node;
typedef struct list
{
int size;
struct node *head;
} list;
// 初始化新节点
node *get_new_node(int val)
{
node *p = (node *)malloc(sizeof(node));
p->data = val;
p->next = NULL;
return p;
}
// 初始化链表
list *init()
{
list *p = (list *)malloc(sizeof(list));
p->head = get_new_node(0);
p->size = 0;
return p;
}
// 删除链表
void delete_list(list *p)
{
node *q = p->head;
// 先释放节点,在释放链表
for (int i = 0; i <= p->size; i++) // <=删除头节点
{
node *t = q->next;
free(q);
q = t;
}
free(p);
}
// 查看链表
void show_list(list *l)
{
printf("----size=%d----\n", l->size);
for (node *p = l->head->next; p != NULL; p = p->next)
{
printf("%d->", p->data);
}
printf("NULL\n--------\n");
}
// ind 位置插入val节点
int insert_ele(list *l, int ind, int val)
{
if (ind > l->size) //位置不存在
{
return 1;
}
// 找到之前的元素
node *p = l->head;
for (int i = 0; i < ind; i++) // 从前向后找到ind的前一个节点
{
p = p->next;
}
node *q = get_new_node(val); // 获取新节点
q->next = p->next; // 调整指针
p->next = q;
l->size++;
return 0;
}
// 删除节点
int delete_ele(list *l, int ind)
{
if (l->size <= ind) // 节点不存在
{
return 1;
}
// 找到之前的元素
node *p = l->head;
for (int i = 0; i < ind; i++) // 从前向后找到ind的前一个节点
{
p = p->next;
}
node *q = p->next;
p->next = q->next;
free(q);
l->size--;
return 0;
}
int main()
{
int n; // 操作次数
scanf("%d", &n);
list *l = init();
for (int i = 0; i < n; i++)
{
int a, b;
scanf("%d", &a);
if (a == 0) // a = 0 新增
{
scanf("%d%d", &a, &b);
insert_ele(l, a, b);
}
else if (a == 1) // a = 1 删除
{
scanf("%d", &a);
delete_ele(l, a);
}
show_list(l);
}
delete_list(l);
l = NULL;
return 0;
}
- 新增代码对比
- 删除代码对比