定义:咱们如何把现实中大量而复杂的问题以特定的数据类型和特定的存储结构保存到主内存器中(内存),以及在此基础上为实现某个功能(好比查找某个元素,删除某个元素,对全部元素进行排序)而执行的相应操做,这个相应的操做也叫算法算法
数据结构 = 个体 + 个体的关系数组
算法 = 对存储结构的操做安全
算法:解题的方法和步骤数据结构
衡量算法的标准:函数
地址:内存单元的编号,从0开始的非负整数指针
指针:指针就是地址,指针变量是存放内存单元地址的变量,指针的本质是一个操做受限的非负整数code
分类:排序
#include <stdio.h> int main(void) { // p是一个变量名字,int * 表示p变量只能存储int类型变量的地址 int *p; int i = 10; int j; p = &i; // p保存了i的地址,p指向i // 修改p的值不影响i的值,修改i的值不影响p的值 // *p等于i j = *p; // 等价于 j = i printf("%d\n", *p); printf("%d\n", j); return 0; }
#include <stdio.h> // 不是定义了一个名字叫作 *p的形参,而是定义了一个形参,该形参的名字p,它的类型是int * void f(int *p) { *p = 100; } int main(void) { int i = 9; int *p = &i; f(p); printf("%d\n", i ); return 0; }
#include <stdio.h> void show_array(int *p , int len) { // p[0] == *p p[0] = -1; // p[i]就是主函数a[i] int i = 0; for (i = 0; i < len; i++) { printf("%d\n",p[i] ); } } int main(void) { /* 一惟数组名是个指针常量,它存放的是一惟数组第一个元素的地址, 它的值不能改变,一惟数组名指向的是数组的第一个元素,也就是 a执向a[0] 下标和指针的关系 a[i] <==> *(a+i) */ int a[5] = {1,2.3,4,5,}; // a等价于&a[0] , &a[0]自己就是int * 类型 show_array(a,5); printf("%d\n", a[0]); return 0; }
#include <stdio.h> int main(void) { double *p; double x = 99.9; // x占8个字节,1字节是8位,1字节一个地址 ,p里面存放了首地址 p = &x; double arr[3] = {1.1,2.2,3.3,}; double *q; double *q1; q = &arr[0]; printf("%p\n", q); // %p实际就是以十六进制输出 q1 = &arr[1]; printf("%p\n", q1); // 相差了8个字节 return 0; }
#include <stdio.h> void f(int **q); int main(int argc, char const *argv[]) { int i = 9; int *p = &i; // int *p , p = &i; printf("%p\n",p ); f(&p); printf("%p\n",p ); return 0; } void f(int **q) { *q = (int*)0XFFFFF; }
这样写是不安全的,可是这个理是这样的,不是修改指针的很简单,内存
#include <stdio.h> void f(int *p); int main(void) { int i =10; f(&i); printf("%d\n", i); return 0; } void f(int *p) { *p = 20; }
为了表示一些复杂的数据,而普通的基本类型变量没法知足要求字符串
结构体是用户根据实际须要,本身定义的复合数据类型
#include <stdio.h> #include <string.h> struct Student { int sid; char name[200]; int age; }; // 分号不能省 int main(void) { // 第一种方式,可是这样很麻烦 struct Student st = {10 , "张三" ,20}; printf("%d %s %d\n", st.sid , st.name , st.age); // 字符串不能直接赋值,必须调用相应的函数 st.sid = 20; strcpy(st.name , "李四"); st.age = 21; printf("%d %s %d\n", st.sid , st.name , st.age); // 第二种方式,这个最经常使用 struct Student *pst; pst = &st; pst -> sid = 99; // pst->sid 等价于 (*pst).sid 等价于 st.sid return 0; }
pst -> sid : pst所指向的结构体中变量中的sid这个成员
#include <stdio.h> #include <string.h> struct Student { int sid; char name[200]; int age; }; void f(struct Student * pst); void g(struct Student st); void g1(struct Student * pst); int main(void) { struct Student st; f(&st); //printf("%d %s %d\n", st.sid , st.name , st.age); //g(st); g1(&st); return 0; } // 用于数据的输入 void f(struct Student * pst) { (*pst).sid = 99; strcpy(pst -> name , "张三"); pst -> age = 30; } // 用于数据的输出,可是这种方法费时间,不推荐 void g(struct Student st) { printf("%d %s %d\n", st.sid , st.name , st.age); } // 用于数据的输出,推荐使用这种方式 void g1(struct Student * pst) { printf("%d %s %d\n", pst->sid , pst->name , pst->age); }
重点看代码和注释
#include <stdio.h> #include <stdlib.h> int main(void) { int a[5] = {3,9,5,6,2}; int len; printf("请输入你须要的分配数组的长度:\n"); scanf("%d" , &len); int * PArr = (int *)malloc(sizeof(int)*len); // *PArr = 3; //相似于a[0] = 3 // PArr[1] = 9; //相似于a[1] = 9 // printf("%d %d\n", *PArr , PArr[1]); // 固然了,这个时候咱们能够把pArr看成一个普通的数组来使用 int i; for (i = 0; i < len; ++i) { scanf("%d" , &PArr[i]); } int j; for (j = 0; j < len; ++j) { printf("%d\n", PArr[j]); } free(PArr); // 把Parr所表明的动态分配的20个字节内存释放 return 0; }
重点看代码和注释
#include <stdio.h> #include <stdlib.h> struct Student { int sid; int age; }; struct Student * CreateStudent(void); void ShowStudent(struct Student * ps); int main(void) { struct Student * ps; ps = CreateStudent(); ShowStudent(ps); return 0; } struct Student * CreateStudent(void) { // 开辟一个新空间,使用malloc函数,类型是咱们想要的类型 struct Student * p = (struct Student * )malloc(sizeof(struct Student)); p->sid = 88; p->age = 99; return p; } void ShowStudent(struct Student * pst) { printf("%d %d\n", pst->sid , pst->age); }