大家好呀,最近学校要考数据结构,虽然我们在日常游戏开发或者其他软件开发中几乎用不到太多数据结构的知识用到也是多叉树 , A* , 深度优先, 广度优先什么的(但是这些东西很多人已经为我们提前做过准备好了),不过技多不压身如是说也 ; =_= ;
这里也是我一直在看的B站的一个老师的视频,也就是说,这些文章其实是我的笔记 狗头
数据结构和算法的定义
定义如下:
数据结构是一种存储,组织数据的方式,旨在便于访问和修改.
没有一种单一的数据结构对所有用途均有效,所以需要知道几种 数据结构优势和局限
算法是一个有穷规则的集合,它用规则规定了解某一特定类型问题的运算序列,
或者规定了任务执行或问题求解的一系列步骤
数据结构和算法属于相互依存的关系,数据结构是算法的基础,算法是数据结构的应用
我们就回顾一下C语言学过的知识吧,但是以后不一定会只用C语言实现,还会用到其他语言
函数
这个不多说了,想必大家炉火纯青,什么有参函数无参函数,嗯,全都是最基本的东西
C语言中的字符串
字符串基础知识点
一,字符串末尾有反斜杠0即 ‘\0’,即在C语言中用字符型数组来表示字符串
二,如果直接对字符型数组赋值字符串是不能的,字符串是不能直接赋值的,需要用strcpy 函数来实现,同时加上#include<stdlib.h>头文件
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| #include <stdio.h> #include <string.h> #include <stdlib.h>
int main() { char str1[] = "Hello World"; printf("方法1: %s\n", str1); char str2[20]; strcpy(str2, "C Programming"); printf("方法2: %s\n", str2); char str3[10]; strncpy(str3, "Safe Copy", sizeof(str3) - 1); str3[sizeof(str3) - 1] = '\0'; printf("方法3: %s\n", str3); char *str4 = "Pointer String"; printf("方法4: %s\n", str4); char str5[6]; str5[0] = 'H'; str5[1] = 'i'; str5[2] = '\0'; printf("方法5: %s\n", str5); char *str6 = malloc(20 * sizeof(char)); if (str6 != NULL) { strcpy(str6, "Dynamic Memory"); printf("方法6: %s\n", str6); free(str6); } return 0; }
|
虚拟内存地址
内存条,显卡,各种适配卡都有其各自的存储地址空间
操作系统将这些设备的存储地址空间抽象成一个巨大的一维数组空间
对于内存的每一个字节会分配一个32位或64位的编号,这个编号称为内存地址
这里先用一些代码来直观表述,不过我们不需要理解目前这些代码的意思,等以后学到栈的时候你可以再看看这些东西这样更好理解
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| #include <stdio.h> #include <string.h> #include <stdlib.h>
int main() { char stack_str[] = "Stack Memory"; char stack_buffer[20]; char *heap_str = malloc(20 * sizeof(char)); strcpy(heap_str, "Heap Memory"); static char data_str[] = "Data Segment"; char *const_str = "Read-Only Constant"; printf("=== 虚拟内存地址分布 ===\n"); printf("栈区地址:\n"); printf(" stack_str: %p (内容: %s)\n", (void*)stack_str, stack_str); printf(" stack_buffer: %p\n\n", (void*)stack_buffer); printf("堆区地址:\n"); printf(" heap_str: %p (内容: %s)\n\n", (void*)heap_str, heap_str); printf("数据段地址:\n"); printf(" data_str: %p (内容: %s)\n\n", (void*)data_str, data_str); printf("代码段地址(只读):\n"); printf(" const_str: %p (内容: %s)\n", (void*)const_str, const_str); printf(" 字符串常量: %p (内容: %s)\n\n", (void*)"Literal String", "Literal String"); printf("=== 指针操作演示 ===\n"); printf("stack_str[0]的地址: %p,值: %c\n", (void*)&stack_str[0], stack_str[0]); printf("heap_str指针的地址: %p,值: %p\n", (void*)&heap_str, (void*)heap_str); stack_str[0] = 'S'; heap_str[0] = 'H'; printf("\n修改后:\n"); printf(" stack_str: %s\n", stack_str); printf(" heap_str: %s\n", heap_str); free(heap_str); return 0; }
|


数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
|
数组我们也不说了,这个也是我们所熟知的离不开的东西
不过提起数组还有一个概念我们也是经常使用到的——-那就是数组长度
这就离不开一个关键字 sizeof
这个大致看看就行了,我们主要需要的是c语言的数组的长度求法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| #include<stdio.h> int main() {
int a[]={16,47,89,42,38}; for(int i=0;i<sizeof(a)/sizeof(a[0]);i++){ printf("%d\n",a[i]); } }
|
指针
这个在C语言中非常重要其实
指针是用来存放内存地址的变量 ,这里我们就先了解最基本的就行
指针基本符号运用
这里先了解指针的一些基本符号比如“ * ” 和 “ & ”
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 26 27 28
|
#include <stdio.h> int main(){ int a=5; int *p=&a; printf("a值为%d,地址为%p\n",a,&a); printf("p值为%p,地址为%p",p,&p);
return 0; }
|
指针与函数
同样的,指针在函数里使用也是及其广泛的,这里我们就以最经典的swap 交换函数为例
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 26 27 28 29
| #include<stdio.h>
void swap(int *a,int *b){ int temp; temp=*a; *a=*b; *b=temp; printf("交换后%d %d",*a,*b); } int main(){ int m; int n; printf("m值为:"); scanf("%d",&m); printf("\nn值为:"); scanf("%d",&n);
swap(&m,&n); printf("\n交换前%d %d",m,n); return 0; }
|
指针与数组
同样的指针在数组里运用也是非常多的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
#include <stdio.h> int main(){ int a[]={15,22,67,43,87}; int *p; p=a;
int len=sizeof(a)/sizeof(a[0]); for(int i=0;i<len;i++){ printf("%d\n",a[i]); } for(int i=0;i<len;i++){ printf("%d\n",*(p+i)); } }
|
结构体
如果你学过Java JavaScript 和C#的话,会发现结构体和 面向对象中的类 是不是很像呢
因此在c中,结构体和typedef使用也是及其广泛的,假如你使用c语言加其他拓展库制作游戏的话,这个绝对是离不开的
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
|
#include<stdio.h>
struct point{ int x; int y; }; struct point creatPoint(int x,int y){ struct point temp; temp.x=x; temp.y=y; return temp; } int main(){ struct point p; p=creatPoint(5,10); printf("%d\n",p.x); printf("%d\n",p.y); return 0; }
|
同样的结构体也可以和指针一起使用
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 26 27 28 29 30 31 32 33
|
#include <stdio.h> struct point{ int x; int y; }; int main(){ struct point p; p.x=5; p.y=10; struct point *pp; pp=&p; (*pp).x=10; (*pp).y=5; printf("x=%d,y=%d\n",p.x,p.y); printf("x=%d,y=%d\n",pp->x,pp->y); return 0; }
|
对了,提起结构体struct就不得不得不提另一个关键字 ——-typedef
这个主要和struct一起使用(毕竟每次使用struct都要写一个struct关键字,非常麻烦,所以我们可以直接用typedef定义的别名尽量来模仿面向对象语言里的类的属性调用的写法)
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
|
#include<stdio.h> typedef struct{ int x; int y; }po;
int main(){ po p; p.x=5; p.y=10; printf("%d\n",p.x); printf("%d\n",p.y); return 0; }
|
内存
C程序编译后会以三种形式使用内存
静态/全局内存
静态声明的变量和全局变量使用这部分内存,这些变量在程序开始运行时分配,直到程序终才消失
自动内存(栈内存)
函数内部声明的变量使用这部分内存,在函数被调用时才创建
动态内存(堆内存)
根据需求编写代码动态分配内存可以编写代码释放,内存中的内容直到释放才消失
这里就用具体的代码来看看如何使用malloc函数吧
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
|
#include<stdio.h> #include<stdlib.h>
typedef struct{ int x; int y; }po;
int main(){ po *p; p=(po*)malloc(sizeof(po)); p->x=5; p->y=10; printf("%d\n",p->x); printf("%d\n",p->y); }
|
文件的存储与读取
这个由于是我们在学数据结构所以不提了,包括C语言数据类型什么的 switch case什么的 循环什么的 if else什么的 宏定义什么的也不需要多说了,因为我不仅仅只用c语言来写数据结构
以后会把这些挖的坑填上,OK,随便扯了一些主要的基本回顾知识 see ya ~ ~ ~

评论区