復習C語言中的5中基本類型,以及各個類型占用了多少個字節:
#include <stdio.h> int main(void) { printf("int=%d\n", sizeof(short int)); printf("int=%d\n", sizeof(int)); printf("int=%d\n", sizeof(long int)); printf("char=%d\n", sizeof(char)); printf("float=%d\n", sizeof(float)); printf("float=%d\n", sizeof(double)); return 0; }
復習數組, 常量指針, 變量指針, 常量指針的指向地址是不能改變的, 但是變量指針的指向地址是可以改變的:
#include <stdio.h> int main() { int i; //a為常量指針 int a[] = {4,5,6,7}; int len = sizeof(a)/sizeof(a[0]); //循環數組,并獲取數組中的值; for(i=0 ;i<len; i++) { printf("%d\n",a[i]); }; for(i=0 ;i<len; i++) { printf("%d\n",*(a+i)); }; //定義一個指針, 指向數組, 此時的指針pa為變量指針 int* pa; pa = a; for(i=0 ;i<len; i++) { printf("%d\n", pa[i]); } for(i=0 ;i<len; i++) { printf("%d\n", *(pa+i)); } //讓指針 pa++ ,輸出數組的指針 printf("%d\n", *(pa++)); //讓數組 a++ ,輸出結果, 會報錯, 因為a是常量指針, 無法改變的; //printf("%d\n", a++); return 0; }
通過指針修改數組, 和直接修改數組的方式:
#include <stdio.h> int main() { int ar[] = {1,2,3,4}; int* p; p = ar; //*p = 0; //*p指向p的第一個元素; p[0] = 0; //這個上一行的代碼效果一模一樣; //*(p+1) = 0; //這一行和上面一行效果也是一樣的 p[1] = 0; printf("%d\n",ar[0]); printf("%d\n",ar[1]); return 0; }
在調用函數的時候,可以傳值:
#include <stdio.h> void Exchg1(int x, int y) { int tmp; tmp=x; x=y; y=tmp; printf("x=%d,y=%d\n",x,y); } int main() { int a=4,b=6; Exchg1 (a,b) ; printf("a=%d,b=%d\n",a,b); return 0; }
也可以傳指針, 指針的話就變成后面的回調函數了:
#include <stdio.h> void Exchg2(int *px, int *py) { int tmp=*px; *px=*py; *py=tmp; printf("*px=%d,*py=%d\n",*px,*py); } int main() { int a=4; int b=6; Exchg2( &a,&b); printf("a=%d,b=%d\n", a, b); return 0; }
指針是c中的一大玩點, 但是指針終究是指針 , 如果參數為一個數組, 指針是無法獲取到指針對應的值的長度的, 所以要把數組給一個函數, 都要把數組的長度作為參數傳遞?這個有待考證
#include <stdio.h> void run(int *p, int *p1) { printf("p 的長度是%d\n", (int)sizeof(*p)); } int main() { int a[] = {1,2,3,4,5,6,7,8}; run(a, b); printf("a 的長度是 : %d\n", (int)sizeof(a)); return 0; } //輸出: //p 的長度是 : 4 //a 的長度是 : 32
#include <stdio.h> //float average( int*p 一樣 ,int len) { float average( int a[] ,int len) { float val; int sum = 0; //printf("%d\n", a); for(int i=0; a[i]!=9999; i++) { printf("%d\n", a[i]); }; a[0] = 9; return val; } int main() { int x[] = {1,2,3,4,5,6,7,8,9,10,9999}; float av; //c語言中的指針不帶有長度信息, 必須把長度作為參數; av = average(x, sizeof(x)/4); printf("%d\n", x[0]); return 0; }
定義數組的變量,即為這個數組的首地址, 把數組作為參數的時候, 被調用的函數中的參數為這個數字的引用:
#include <stdio.h> void average( int a[] ) { a[0] = 9; } int main() { int x[] = {1,2,3,4,5,6,7,8,9,10,9999}; average(x); //x的第一個值是 : 9 printf("x的第一個值是 : %d", x[0]); return 0; }
接受參數的時候, 可以定義一個數組作為形參數:
#include <stdio.h> void average( int* p ) { p[0] = 9; } int main() { int x[] = {1,2,3,4,5,6,7,8,9,10,9999}; average(x); //輸出:x的第一個值是 : 9 printf("x的第一個值是 : %d", x[0]); return 0; }
一個字符或者數字只是一個變量, 把以上兩種類型作為參數的時候, 實際上傳遞的只是一個原始值的復制品:
#include <stdio.h> void test( int p ) { p = 9; } int main() { int x = 0; test(x); //輸出:x的第一個值是 : 0 printf("x的值是 : %d", x); return 0; }
也可以把字符或者數字作為一個指針,傳遞給函數, 函數定義的時候接收, 在調用的函數中修改指針, 對應的變量會發生改變:
#include <stdio.h> void test( int* p ) { *p = 9; } int main() { int x = 0; test(&x); //輸出:x的第一個值是 : 9 printf("x的值是 : %d", x); return 0; }
搞笑的數組和指針:
#include <stdio.h> int main() { int a[10]; int *p; int i; for(p = a; p<a+10; p++){ printf("p is %d \n", p); } return 0; }
循環輸入學生的分數,冒泡排序以后重新輸出分數, malloc(Byte):
#include <stdlib.h> #include <stdio.h> void sort( int *s , int len) { int i = 0, j = 0; //冒泡排序 for(i=0; i<len; i++) { for(j=i; j<len; j++) { if( s+j>s+i ) { int temp = 0; temp = *(s+i); *(s+i) = *(s+j); *(s+j) = temp; } } } } int main() { int *a , j , n; scanf("%d\n",&n); a = (int *)malloc(10); for(j=0; j<n; j++) { scanf("%d",a+j); } printf("puts trings\n"); sort(a, n); for(j=0; j<n; j++) { printf("%d\n",*(a+j)); } free(a); return 0; }
實現一個命令行的投票功能, 輸入li或者zhang, 投的票數會自動增加 :
#include <stdio.h> #include <string.h> struct per { char name[20]; int count; }leader[2] = {{"li",0},{"zhang",0}}; int main() { int i , j; int p; char name[20]; printf("enter 'li' or 'zhang' : \n"); for(i = 0; i<6; i++) { scanf("%s\n", name); for(j = 0; j<2; j++) { if(strcmp(leader[j].name, name) == 0) { leader[j].count = leader[j].count+1; }; } } for(i = 0; i<2 ; i++) { printf("user %s, count is %d\n", leader[i].name, leader[i].count); } return 0; }
字符串的復制需要strcpy, 原始類型的復制可以使用左值直接賦值:
#include <stdio.h> #include <string.h> struct st{ char name[10]; int age; }s2; int main() { char c[] = "abcd"; char b[4]; strcpy(b,c); printf("string is : %s\n",b); struct st s1 = {"nono",28}; s2.age = s1.age; printf("s2 age is : %d\n", s2.age); strcpy(s2.name, s1.name); printf("s2 name is : %s\n", s2.name); return 0; }
利用結構體實現簡易的用戶查詢系統, 包含用戶的添加以及查詢:
#include <stdio.h> #include <string.h> #include <stdlib.h> struct user{ int id; char name[20]; char descript[20]; }s[20];//預置20個用戶 int count = 0; void find() { printf("please to enter user id:\n"); int id = 0, i; scanf("%d", &id); for(i=0 ;i <count; i++) { if(s[i].id == id) { printf("user id is %d\n user name is %s \nuser desciprtion %s\n", s[i].id, s[i].name, s[i].descript); } } } void all() { int i = 0; for(i=0 ; i<count; i++) { printf("user name : %d\n", s[i].id ); printf("user name : %s\n", s[i].name ); printf("user desciprtion : %s\n", s[i].descript ); } } void add() { char name[20]; char descript[20]; printf("input user name :\n"); scanf("%s",name); printf("input user desciprtion:\n"); scanf("%s",descript); user s1; //= { count , *name, *descript}; s1.id = count; strcpy(s1.name, name); strcpy(s1.descript, descript); s[count] = s1; count++; } int main() { //用戶的輸入: char ipt[10]; //循環獲取用戶的輸入 printf("%d\n", (int)(sizeof(s)/sizeof(s[0]))); while(1) { printf("\n\n\n\n輸入查詢:\n "); printf("查詢所有輸入:all \n 增加用戶輸入:add\n 查詢詳細輸入:find\n"); //獲取用的輸入 scanf("%s", ipt); printf("%s", ipt); //查看所有的用戶 if(strcmp(ipt, "all")==0) { all(); } //增加一個用戶 if(strcmp(ipt,"add")==0) { add(); } //根據用戶ID, 返回查詢用戶消息 if(strcmp(ipt,"find")==0) { find(); } } return 0; }
內存管理(MM), 通過malloc申請內存,以及使用free返還內存:
#include <stdio.h> #include <stdlib.h> int main() { char *p; p = (char *)malloc(8); int i; for(i=0; i<8; i++) { p[i] = i; } for(i=0; i<8; i++) { printf("address is %p;content is %c\n",&p[i],p[i]); } free(p); return 0; }
#include <stdio.h> #include <stdlib.h> int main() { char *p; p = (char *)malloc(8); int i; for(i=0; i<8; i++) { p[i] = i; } for(i=0; i<8; i++) { printf("address is %p;content is %c\n",&p[i],p[i]); } free(p); return 0; }
買車的實現:
#include <stdio.h> #include <string.h> #include <stdlib.h> struct car{ char maker[10]; int deposit; }; struct people{ char name[10]; int deposit; car *c; }; void buy(people *p) { car *c = (car *)malloc(sizeof(car)); strcpy(c->maker, "bench"); c->deposit = 10; p->deposit -= c->deposit; p->c = c;; } void discard(people *p) { free(p->c); p->c = NULL; } int main() { people p = {"nono",100,NULL}; printf("people name is : %s\n", p.name); printf("people deposit is : %d\n", p.deposit); buy(&p); printf("after buy it , people deposit is : %d\n", p.deposit); printf("%s has a car, the car name is %s\n",p.name, p.c->maker); discard(&p); return 0; }
鏈表的使用, 鏈表和數組的區別以及各自不同的使用場景,有頭節點和無頭節點的區別和區別:
鏈表是動態生成的, 可控性比數組好非常多, 數組的長度是固定的,但是鏈表可以無限延長, 對于鏈表的操作也比較靈活, 可以往鏈表的中間插入數據, 但是數組的插入是非常繁瑣的;
有頭鏈表保障了鏈表起碼有一個開始, 對于數據的操作更靈活, 無頭鏈表必須保證,頭部有一個數據, 否者無法做后續操作:
#include <stdio.h> #include <string.h> #include <stdlib.h> /* *網吧用戶管理系統 */ struct User { //用戶名 char name[10]; //用戶密碼 char pass[10]; //用戶金額 int deposit; User* next; }; //察看所有 void showAll(User *user) { User *curr = user; while(curr->next) { curr = curr->next; printf("user : %s\ndeposit:%d\n",curr->name,curr->deposit); } } //添加用戶 void add(User *user) { //局部創建的變量, 在離開該函數的作用域后, 會被自動清空; char name[10]; char pass[10]; int deposit = 0; printf("please enter user name :\n"); scanf("%s",name); printf("please enter user pass :\n"); scanf("%s",pass); printf("please enter user deposit :\n"); scanf("%d",&deposit); //必須使用MM申請空間, 然后再往user下添加數據 User *u = (User*)malloc(sizeof(User)); u->deposit = deposit; strcpy(u->name, name); strcpy(u->pass, pass); u->next = NULL; //循環,直到,user沒有下一個數據; while(user->next){ user = user->next; printf("find next\n"); }; user->next = u; //printf("next is :%p\n",user->next); } void find(User *user) { char name[10]; printf("enter user name to find : \n"); scanf("%s", name); User *curr = user; while(curr->next) { if( strcmp(curr->next->name, name) == 0 ) { printf("user is %s\ndeposit is %d\n", curr->next->name, curr->next->deposit); return ; } curr = curr->next; } } //刪除用戶 void remove(User *user) { char name[10]; printf("enter user name to rmove : \n"); //數組的話只要傳name,因為name本來就是一個地址 //字符和數字要加&因為,他們本身是數據,要根據地址改數據; scanf("%s", name); User* curr = user->next; while( curr->next ) { if( strcmp(curr->next->name, name) == 0 ) { User *now = curr->next; curr->next = now->next; free(now); printf("removed\n"); return ; } user = user->next; } } int main() { User user = {"","",0,NULL}; char cmdline[10]; while(1) { //輸出查看,添加,刪除命令 printf("查看所有:all\n添加用戶:add\n刪除用戶:remove\n查找用戶信息:find\n"); scanf("%s",cmdline); printf("you are enter : %s\n", cmdline); //如果是察看 if(strcmp("all",cmdline) == 0) { showAll(&user); }; //如果是添加 if(strcmp("add",cmdline)==0) { add(&user); } //如果是刪除 if(strcmp("remove",cmdline)==0) { remove(&user); } //如果是刪除 if(strcmp("find",cmdline)==0) { find(&user); } } return 0; }
引用相關, 定義一個引用的時候, 必須初始化, 但是定義指針不要強制初始化, 定義完畢引用以后,無法解綁,被強制綁定, 無法重新賦值 :
#include <stdio.h> struct stu { char name[16]; int age; }; int main() { //refference引用是強化版的指針 int a = 100; //定義一個引用的時候, 必須初始化, 但是定義指針不要強制初始化 //定義完畢引用以后,無法解綁,被強制綁定, 無法重新賦值 int&b = a; printf("b = %d, address : %p\n", b,&b); printf("a = %d, address : %p", a,&a); stu s = {"nono",10}; stu& s1 = s; printf("把s1的age改成100"); s1.age = 100; printf("s的age is %d\n", s.age);\ return 0; }
引用可以作為返回值:
#include <stdio.h> int b = 1000; int& test() { //如果我把b定義在test函數內部, 會報錯, 因為函數執行完畢以后, 內部的所有變量都會被銷毀; int& a = b; return a; } int main() { int& a = test(); printf("The a is %d\n", a); return 0; }
可以把引用作為返回值, 但是這種寫法不太好閱讀, 不方便閱讀理解:
#include <stdio.h> int number = 0; int& test() { return number; } int main() { test() = 4; printf("%d\n", number); return 0; }
廈門點燃未來網絡科技有限公司, 是廈門最好的微信應用, 小程序, 微信網站, 公眾號開發公司
文章列表