定義:咱們如何把現實中大量而複雜的問題以特定的數據類型和特定的存儲結構保存到主內存器中(內存),以及在此基礎上爲實現某個功能(好比查找某個元素,刪除某個元素,對全部元素進行排序)而執行的相應操做,這個相應的操做也叫算法算法
數據結構 = 個體 + 個體的關係數組
算法 = 對存儲結構的操做安全
算法:解題的方法和步驟數據結構
衡量算法的標準:函數
地址:內存單元的編號,從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); }