前言
爲了更加學習Java 虛擬機的知識,於是決定重新學習C語言知識。
第一個程序
#include <stdio.h> int main() { printf("Hello world!\n"); return 0; }
運行結果:
改變一下輸出方式:
#include <stdio.h> int main() { printf("\n\ Hello\n\ world!\n"); return 0; }
運行結果:
\單獨使用表示延續下一行的代碼。
下面是轉義字符的對照表:
轉義字符 | 意義 | ASCII碼值(十進制) |
---|---|---|
\a | 響鈴(BEL) | 007 |
\b | 退格(BS) ,將當前位置移到前一列 | 008 |
\f | 換頁(FF),將當前位置移到下頁開頭 | 012 |
\n | 換行(LF) ,將當前位置移到下一行開頭 | 010 |
\r | 回車(CR) ,將當前位置移到本行開頭 | 013 |
\t | 水平製表(HT) | 009 |
\v | 垂直製表(VT) | 011 |
\' | 單引號 | 039 |
\" | 雙引號 | 034 |
\\ | 反斜槓 | 092 |
C語言關鍵字:
關鍵字 | 說明 |
---|---|
auto | 聲明自動變量 |
break | 跳出當前循環 |
case | 開關語句分支 |
char | 聲明字符型變量或函數返回值類型 |
const | 定義常量,如果一個變量被 const 修飾,那麼它的值就不能再被改變 |
continue | 結束當前循環,開始下一輪循環 |
default | 開關語句中的"其它"分支 |
do | 循環語句的循環體 |
double | 聲明雙精度浮點型變量或函數返回值類型 |
else | 條件語句否定分支(與 if 連用) |
enum | 聲明枚舉類型 |
extern | 聲明變量或函數是在其它文件或本文件的其他位置定義 |
float | 聲明浮點型變量或函數返回值類型 |
for | 一種循環語句 |
goto | 無條件跳轉語句 |
if | 條件語句 |
int | 聲明整型變量或函數 |
long | 聲明長整型變量或函數返回值類型 |
register | 聲明寄存器變量 |
return | 子程序返回語句(可以帶參數,也可不帶參數) |
short | 聲明短整型變量或函數 |
signed | 聲明有符號類型變量或函數 |
sizeof | 計算數據類型或變量長度(即所佔字節數) |
static | 聲明靜態變量 |
struct | 聲明結構體類型 |
switch | 用於開關語句 |
typedef | 用以給數據類型取別名 |
unsigned | 聲明無符號類型變量或函數 |
union | 聲明共用體類型 |
void | 聲明函數無返回值或無參數,聲明無類型指針 |
volatile | 說明變量在程序執行中可被隱含地改變 |
while | 循環語句的循環條件 |
C99 新增關鍵字
_Bool | _Complex | _Imaginary | inline | restrict |
C11 新增關鍵字
_Alignas | _Alignof | _Atomic | _Generic | _Noreturn |
_Static_assert | _Thread_local |
數據類型
類型 | 存儲大小 | 值範圍 |
---|---|---|
char | 1 字節 | -128 到 127 或 0 到 255 |
unsigned char | 1 字節 | 0 到 255 |
signed char | 1 字節 | -128 到 127 |
int | 2 或 4 字節 | -32,768 到 32,767 或 -2,147,483,648 到 2,147,483,647 |
unsigned int | 2 或 4 字節 | 0 到 65,535 或 0 到 4,294,967,295 |
short | 2 字節 | -32,768 到 32,767 |
unsigned short | 2 字節 | 0 到 65,535 |
long | 4 字節 | -2,147,483,648 到 2,147,483,647 |
unsigned long | 4 字節 | 0 到 4,294,967,295 |
#include <stdio.h> int main() { int a; char b; float c; double d; a = 520; b = 'F'; c = 3.14; d = 3.1415926; printf("int 類型%d \n",a); printf("char 類型%c \n",b); printf("float 類型%.2f \n",c); //.2 是精確到小數點後兩位 printf("double 類型%11.9f \n",d); // 11.9 表示總共11位,小數9位。 return 0; }
運行結果:
define的案例
#define NAME "天天向上" int main() { printf("好好學習,%s\n",NAME); return 0; }
運行結果:
#include <stdio.h> #define PI 3.14 int main () { printf("%s",PI); #undef PI // 終止PI的作用域, 後面的代碼就不可以使用PI了。 return 0; }
嵌套宏:
#include <stdio.h> #define PI 3.14 #define R 6371 #define V PI * R * R * R * 4/3 int main () { printf("%f",V); return 0; }
運行結果:
define 的其他用法:
#include <stdio.h> #define MAX(x,y) ((x>y) ? (x) : (y)) int main () { printf("較大的數爲:%d",MAX(3,5)); return 0; }
運行結果:
#include <stdio.h> #define STR(s) # s int main () { printf("%s",STR(HELLO)); return 0; }
運行結果:
#include <stdio.h> #define STR(s,s1) s ## s1 int main () { printf("%d",STR(2,3)); return 0; }
運行結果:
long long int 和sizeof案例
#include <stdio.h> int main() { long long int a ; a = 1000000000000000; printf("long long int:%lld\n",a); printf("long long int:%d\n", sizeof(a)); return 0; }
運行結果:
unsigned和signed案例
是否帶符號位,不帶符號位可以存更大的正數。
#include <stdio.h> int main() { signed int a ; unsigned int b; a = 2147483647; b = 4294967284; printf("int:%d\n",a); printf("unsigned int:%ud\n",b); return 0; }
運行結果:
char 和 ASCII表
#include <stdio.h> int main() { char a = 'a'; printf("char:%d,int:%c\n",a,a); return 0; }
運行結果:
字符數組:
#include <stdio.h> int main() { char a[6] = {'a','b','c','d','e','\0'}; printf("char:%s\n",a); return 0; }
運行結果:
字符串
#include <stdio.h> int main() { char a[] = "abcde"; printf("char:%s\n",a); return 0; }
運行結果:
extern 關鍵字用法
文件:addtwonum.c
#include <stdio.h> /*外部變量聲明*/ extern int x ; extern int y ; int addtwonum() { return x+y; }
主函數:
#include <stdio.h> /*定義兩個全局變量*/ int x=1; int y=2; int addtwonum(); int main(void) { int result; result = addtwonum(); printf("result 爲: %d\n",result); return 0; }
運行結果:
const 關鍵字
#include <stdio.h> int main() { const int LENGTH = 10; const int WIDTH = 5; const char NEWLINE = '\n'; int area; area = LENGTH * WIDTH; printf("value of area : %d", area); printf("%c", NEWLINE); return 0; }
運行結果:
math函數
#include <stdio.h> #include <math.h> int main() { int i = pow(2,3); printf("value of area : %d", i); return 0; }
運行結果:
if 語句
#include <stdio.h> int main() { int a = 1; if(a == 1){ printf("a == 1"); } return 0; }
運行結果:
int a ; scanf("%d",&a); -- 輸入函數
if else
#include <stdio.h> int main() { int a ; scanf("%d",&a); if(a == 1){ printf("a == 1"); }else{ printf("a != 1"); } return 0; }
運行結果:
switch 表達式
#include <stdio.h> int main() { int a; printf("input integer number: "); scanf("%d",&a); switch(a) { case 1:printf("Monday\n"); break; case 2:printf("Tuesday\n"); break; case 3:printf("Wednesday\n"); break; case 4:printf("Thursday\n"); break; case 5:printf("Friday\n"); break; case 6:printf("Saturday\n"); break; case 7:printf("Sunday\n"); break; default:printf("error\n"); } }
運行結果:
while 循環
#include <stdio.h> int main () { /* 局部變量定義 */ int a = 10; /* while 循環執行 */ while( a < 20 ) { printf("a 的值: %d\n", a); a++; } return 0; }
運行結果:
do while 循環
#include <stdio.h> int main () { /* 局部變量定義 */ int a = 10; /* do 循環執行,在條件被測試之前至少執行一次 */ do { printf("a 的值: %d\n", a); a = a + 1; }while( a < 20 ); return 0; }
運行結果:
getchar 函數
#include <stdio.h> int main () { int count ; printf("請輸入字符串:"); while(getchar() != '\n'){ count++; } printf("你輸入了%d個字符",count); return 0; }
運行結果:
for 循環
#include <stdio.h> int main () { /* for 循環執行 */ for( int a = 10; a < 20; a = a + 1 ) { printf("a 的值: %d\n", a); } return 0; }
運行結果:
break
#include <stdio.h> int main () { /* 局部變量定義 */ int a = 10; /* while 循環執行 */ while( a < 20 ) { printf("a 的值: %d\n", a); a++; if( a > 15) { /* 使用 break 語句終止循環 */ break; } } return 0; }
運行結果:
continue
#include <stdio.h> int main () { /* 局部變量定義 */ int a = 10; /* do 循環執行 */ do { if( a == 15) { /* 跳過迭代 */ a = a + 1; continue; } printf("a 的值: %d\n", a); a++; }while( a < 20 ); return 0; }
運行結果:
goto
#include <stdio.h> int main () { /* 局部變量定義 */ int a = 10; /* do 循環執行 */ LOOP:do { if( a == 15) { /* 跳過迭代 */ a = a + 1; goto LOOP; } printf("a 的值: %d\n", a); a++; }while( a < 20 ); return 0; }
運行結果:
函數
#include <stdio.h> /* 函數聲明 */ int max(int num1, int num2); int main() { int i ; i = max(1,2); printf("i = %d",i); } int max(int num1, int num2) { /* 局部變量聲明 */ int result; if (num1 > num2) result = num1; else result = num2; return result; }
運行結果:
數組
#include <stdio.h> int main () { /* 局部變量定義 */ int a[5] = {1,2,3,4,5}; for (int i = 0; i < 5; i++) { printf("%d\n" , a[i]); } return 0; }
運行結果:
數組支持指定元素初始化。
字符串
#include <stdio.h> #include <string.h> int main () { /* 局部變量定義 */ char a[] = "I love you"; printf("sizeof str = %d\n",sizeof(a)); printf("strlen str = %u\n",strlen(a)); return 0; }
運行結果
strcpy -- 拷貝字符串 strncpy -- 拷貝N位字符串 strcat -- 拼接字符串
strcmp -- 比較字符串
二維數組
#include <stdio.h> int main () { /* 局部變量定義 */ int a[3][3] = {1,2,3,4,5,6,7,8,9}; for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { printf("a[%d][%d]=%d ",i,j,a[i][j]); } printf("\n"); } return 0; }
運行結果:
int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}}; -- 也可以這麼寫
指針
#include <stdio.h> int main () { int a = 3; int *pa = &a; printf("pa = %d \n",pa); printf("*pa = %d \n",*pa); *pa = 4; printf("*pa = %d \n",*pa); return 0; }
運行結果:
指令案例2
#include <stdio.h> int main () { char a; char *pa = &a; printf("請輸入一個字符:"); fflush(stdout); scanf("%c",&a); printf("a = %c\n",a); getchar(); printf("請輸入另一個字符:"); fflush(stdout); scanf("%c",pa); printf("a = %c\n",a); return 0; }
運行結果:
指針案例3
#include <stdio.h> int main () { char str[128]; printf("請出入姓名:"); fflush(stdout); scanf("%s",str); printf("str = %s",str); return 0; }
運行結果:
字符串 str 本身就已經是地址了, 所以scanf 的時候不需要加&。
案例4
#include <stdio.h> int main () { char str[128]; printf("請出入姓名:"); fflush(stdout); scanf("%s",str); printf("str = %p\n",str); printf("str = %p",&str[0]); return 0; }
運行結果:
指針案例5
#include <stdio.h> int main () { int a[5] ; int *pa = a; printf("%p %p %p %p %p \n",&a[0],&a[1],&a[2],&a[3],&a[4]); *(pa) = 5; *(pa+1) = 4; // pa+1 表示指向數組下一個元素的地址。 *(pa+2) = 3; *(pa+3) = 2; *(pa+4) = 1; printf("%d %d %d %d %d \n",a[0],a[1],a[2],a[3],a[4]); return 0; }
運行結果:
指針案例6
#include <stdio.h> int main () { int a[5] ; printf("%p %p %p %p %p \n",&a[0],&a[1],&a[2],&a[3],&a[4]); *(a) = 5; *(a+1) = 4; *(a+2) = 3; *(a+3) = 2; *(a+4) = 1; printf("%d %d %d %d %d \n",a[0],a[1],a[2],a[3],a[4]); return 0; }
運行結果:
指針案例7
#include <stdio.h> #include <string.h> int main () { char *str = "I Love You"; int a = strlen(str); for (int i = 0; i < a; ++i) { printf("%c" ,str[i]); } return 0; }
運行結果:
指令案例8:實現strlen函數
#include <stdio.h> int main () { char str[] = "I Love You"; char *target = str; int count; while(*(target++) != '\0'){ count++; } printf("%d" ,count); return 0; }
運行結果:
指針案例9:指針數組
#include <stdio.h> int main () { char *p[3] = { "I Love You.", "good good study , day day up.", "no pain, no gain." }; for (int i = 0; i < 3; ++i) { printf("%s\n",p[i]); printf("%p\n",p[i]); } return 0; }
運行結果:
指針案例10 :數組指針
#include <stdio.h> int main () { int tmp[3] = {1,2,3}; int (*p)[3] = &tmp; for (int i = 0; i < 3; ++i) { printf("%d\n",*(*p+i)); } return 0; }
運行結果:
指針案例11:二維數組和指針
#include <stdio.h> int main () { int array[3][3] = {0,1,2,3,4,5,6,7,8}; printf("sizeof = %d\n",sizeof(int)); printf("array = %p\n",array); printf("array+1 = %p\n",array+1); // array+1 等於指向下一行數組的地址 printf("*(array+1)+1 = %p\n",*(array+1)+1); // array+1 等於指向下一行數組的地址 return 0; }
運行結果:
void 指針
#include <stdio.h> int main () { int number = 1024; int *pNumber = &number; void *pa = &number; // 任何類型的指針都可以指向void的指針 char str[] = "hello"; char *pStr = str; void *pb = str; printf("%p\n",pa); printf("%p\n",pNumber); printf("%p\n",pStr); printf("%p\n",pb); printf("%d\n",*(int *)pa); // void 強轉成int指針 printf("%s\n",(char *)pb); // void 強轉成char指針 return 0; }
運行結果:
null 指針
#include <stdio.h> int main () { int *pa; // 任何類型的指針都可以指向void的指針 int *pb = NULL; printf("%p\n",pa); printf("%p\n",pb); printf("%d\n",*pb); return 0; }
運行結果:
指針不需要初始化的時候可以指向NULL。
指針的指針
#include <stdio.h> int main () { int num = 520; int *p = # int **pp = &p; printf("%d",**pp); return 0; }
運行結果:
指針指向指針的應用
#include <stdio.h> int main () { char *p[3] = { "I Love You.", "good good study , day day up.", "no pain, no gain." }; char **a; char **b[2]; a = &p[2]; b[0] = &p[0]; b[1] = &p[1]; printf(" %s\n",*a); printf("%s\n",*b[0]); printf("%s\n",*b[1]); return 0; }
運行結果:
二維數組和指針
#include <stdio.h> int main () { int array[3][3] = {0,1,2,3,4,5,6,7,8}; int (*p)[3] = array; for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { printf("%d ",*(*(p+i)+j)); } printf("\n"); } return 0; }
運行結果:
常量指針
#include <stdio.h> int main () { int num = 1024; const int cNum = 88; const int *pcNum = &cNum; printf("cnum = %d,&cnum = %p\n",cNum,&cNum); printf("*pcNum = %d, pcNum = %p\n",*pcNum,pcNum); pcNum = # num = 1025; printf("*pcNum = %d, pcNum = %p\n",*pcNum,pcNum); int num1 = 1024; int * const constNum = &num1; // 常量指針,指針地址不能修改。 *constNum = 1025; printf("*constNum = %d, constNum = %p",*constNum,constNum); const int * const constNum1 = &cNum; // 常量指針,指針地址不能修改,指針解引用也不能修改。 cNum 也需要是常量,不然就可以被修改。 return 0; }
運行結果:
函數與指針
#include <stdio.h> /** * 函數聲明(可以不寫,推薦要寫),並且要在使用函數之前 * @param a * @param b * @return */ void swap(int *a,int *b); /** * 函數實現 * @param a * @param b * @return */ void swap(int *a,int *b){ int temp ; temp = *a; *a = *b; *b = temp; } int main () { int a = 3; int b = 5; printf("a = %d, b = %d\n",a,b); swap(&a,&b); // 使用指針a,b 內存中的值會進行交換。 printf("a = %d, b = %d\n",a,b); return 0; }
運行結果:
注意:數組傳遞,傳遞傳的是數組首地址。
可變參數的函數:
#include <stdio.h> #include <stdarg.h> /** * 函數聲明(可以不寫,推薦要寫),並且要在使用函數之前 * @return */ int sum(int n, ...); /** * 函數實現 * @return */ int sum(int n, ...){ int sum = 0; va_list vap; va_start(vap,n); for (int i = 0; i < n; i++) { sum = sum + va_arg(vap,int); } va_end(vap); return sum; } int main () { int a = 3; int b = 5; printf("a = %d, b = %d\n",a,b); int tot = sum(3,1,2,3); printf("tot = %d\n",tot); return 0; }
運行結果:
指針函數
#include <stdio.h> char * getWord(char c); char * getWord(char c){ switch (c) { case 'A': return "apple"; case 'B': return "banana"; case 'C': return "cat"; case 'D': return "dog"; default: return "None"; } } int main () { char input; printf("請輸入一個字母:"); fflush(stdout); scanf("%c",&input); printf("%s",getWord(input)); return 0; }
運行結果:
不要返回局部變量的指針。
函數指針
#include <stdio.h> int square(int num); int square(int num){ return num*num; } int main () { int num; printf("請輸入一個整數:"); fflush(stdout); scanf("%d",&num); int (*p)(int num); p = □ int squareNum = p(num); printf("%d",squareNum); return 0; }
運行結果:
函數指針作爲參數:
#include <stdio.h> int square(int num); int calc(int (*p)(int),int num); int square(int num){ return num*num; } int calc(int (*p)(int),int num){ return p(num); } int main () { int num; printf("請輸入一個整數:"); fflush(stdout); scanf("%d",&num); int (*p)(int num); p = □ int squareNum = calc(p,num); printf("%d",squareNum); return 0; }
運行結果:
函數出參指針:
#include <stdio.h> int add(int num1, int num2); int sub(int num1, int num2); int calc(int (*p)(int,int),int num1,int num2); int (*select(char c))(int,int); int add(int num1, int num2){ return num1 + num2; } int sub(int num1, int num2){ return num1 - num2; } int calc(int (*p)(int,int),int num1,int num2){ return p(num1,num2); } int (*select(char c)) (int num1,int num2){ switch (c) { case '+' : return &add; case '-' : return ⊂ } } int main () { int num1 = 5,num2 = 3; char c; printf("請輸入(+ or -):"); fflush(stdout); scanf("%c",&c); int (*p)(int num1,int num2); int squareNum = calc(select(c),num1,num2); printf("%d",squareNum); return 0; }
運行結果:
變量的作用域
局部變量和全局變量重名時, 局部會屏蔽全局變量。
static 關鍵字
#include <stdio.h> static int a; int main () { a = 1; printf("%d",a); return 0; }
運行結果:
保護全局變量,不被其他文件使用。
#include <stdio.h> static int a; void function(); void function(){ static int a = 0; printf("%d\n" ,a); a++; } int main () { for (int i = 0; i < 10; ++i) { function(); } return 0; }
運行結果:
內存分配malloc
#include <stdio.h> #include <stdlib.h> int main () { int *p; // 申請內存空間 p = (int *)malloc(sizeof(int)); if(p == NULL){ printf("分配內存失敗\n"); } *p = 7; printf("%d\n",*p); free(p); // 釋放內存 printf("%d\n",*p); printf("%p",p); return 0; }
運行結果:
malloc 案例2
#include <stdio.h> #include <stdlib.h> int main () { int *p = NULL; int num = 10 ; p = (int *)malloc(num * sizeof(int)); p[0] = 1; p[1] = 2; p[2] = 2; p[3] = 2; p[4] = 2; p[5] = 2; p[6] = 2; p[7] = 2; p[8] = 2; p[9] = 2; for (int j = 0; j < 10; ++j) { printf("%d\n",p[j]); } free(p); return 0; }
運行結果:
malloc 案例3
#include <stdio.h> #include <stdlib.h> #include <string.h> int main () { int *p = NULL; int num = 5 ; p = (int *)malloc(num * sizeof(int)); // 初始化數組的值。 memset(p,0,num * sizeof(int)); for (int j = 0; j < num; ++j) { printf("p = %d\n",p[j]); } free(p); int *p1 = (int *)calloc(num, sizeof(int)); for (int j = 0; j < num; ++j) { printf("p1 = %d\n",p1[j]); } return 0; }
運行結果:
realloc
#include <stdio.h> #include <stdlib.h> #include <string.h> int main () { int num = 5; int *p1 = (int *)malloc(num*sizeof(int)); int *p2 = (int *)malloc(10*sizeof(int)); memcpy(p2,p1,10); // p1 拷貝給 p2 free(p2); // 複製並且擴張內存空間。 int *p3 = (int *)realloc(p1,10*sizeof(int)); free(p3); free(p1); return 0; }
動態擴展內存空間
#include <stdio.h> #include <stdlib.h> int main () { int num; int count = 0; int *p = NULL; do{ printf("請輸入數字,-1 表示結束\n"); fflush(stdout); scanf("%d",&num); count++; p = (int *)realloc(p,count*sizeof(int)); if(p == NULL){ exit(1); } p[count-1] = num; }while(num != -1); for (int i = 0; i < count; ++i) { printf("%d\n",p[i]); } return 0; }
運行結果:
地址越界案例:
#include <stdio.h> int main () { char a = 0; char b = 0; int *p = (int *)&b; *p = 258; // 地址越界,導致b不能完整保存258。 printf("%d,%d",a,b); return 0; }
運行結果:
內聯函數
#include <stdio.h> inline int square(int); inline int square(int x){ return x * x; } int main () { for (int i = 0; i < 100; ++i) { printf("square(%d) = %d",i,square(i)); } return 0; }
結構體
#include <stdio.h> #include <string.h> struct Book{ char title[128]; char author[40]; char publisher[40]; float price; unsigned int date; } book; int main () { strcpy(book.author, "lili"); book.date = 19910709; book.price = 3.5; strcpy(book.publisher, "my"); strcpy(book.title, "C語言"); printf("作者:%s\n",book.author); printf("日期:%d\n",book.date); printf("價格:%f\n",book.price); printf("出版社:%s\n",book.publisher); printf("書名:%s\n",book.title); return 0; }
運行結果:
char 類型需要放在一起, 因爲存在對其填充。
結構體取值:
#include <stdio.h> struct Book{ char title[128]; char author[40]; char publisher[40]; float price; int date; } book = { "C語言", "lili", "my", 3.5, 19910709 }; int main () { struct Book *book1; book1 = &book; printf("作者:%s\n",(*book1).author); printf("日期:%d\n",(*book1).date); printf("價格:%f\n",(*book1).price); printf("出版社:%s\n",(*book1).publisher); printf("書名:%s\n",(*book1).title); printf("作者:%s\n",book1 -> author); printf("日期:%d\n",book1 -> date); printf("價格:%f\n",book1 -> price); printf("出版社:%s\n",book1 -> publisher); printf("書名:%s\n",book1 -> title); return 0; }
運行結果:
函數傳遞結構體
#include <stdio.h> struct Date{ int year; int month; int day; }; struct Book{ char title[128]; char author[40]; char publisher[40]; float price; struct Date date; }; struct Book inPut(struct Book book); struct Book inPut(struct Book book){ printf("請輸入書名:"); fflush(stdout); scanf("%s",book.title); printf("請輸入作者:"); fflush(stdout); scanf("%s",book.author); printf("請輸入售價:"); fflush(stdout); scanf("%f",&book.price); printf("請輸入出版日期(yyyy-mm-dd):"); fflush(stdout); scanf("%d-%d-%d",&book.date.year,&book.date.month,&book.date.day); printf("請輸入出版社:"); fflush(stdout); scanf("%s",book.publisher); return book; } int main () { struct Book book1,book2; printf("=============輸入第一本書的信息============\n"); book1 = inPut(book1); printf("=============輸入第二本書的信息============\n"); book2 = inPut(book2); printf("=============打印第一本書的信息============\n"); printf("第一本書的作者:%s\n",book1.author); printf("第一本書的日期:%d-%d-%d\n",book1.date.year,book1.date.month,book1.date.day); printf("第一本書的價格:%f\n",book1.price); printf("第一本書的出版社:%s\n",book1.publisher); printf("第一本書的書名:%s\n",book1.title); printf("=============打印第二本書的信息============\n"); printf("第二本書的作者:%s\n",book2.author); printf("第二本書的日期:%d-%d-%d\n",book2.date.year,book2.date.month,book2.date.day); printf("第二本書的價格:%f\n",book2.price); printf("第二本書的出版社:%s\n",book2.publisher); printf("第二本書的書名:%s\n",book2.title); return 0; }
運行結果:
函數傳遞結構體的指針:
#include <stdio.h> struct Date{ int year; int month; int day; }; struct Book{ char title[128]; char author[40]; char publisher[40]; float price; struct Date date; }; void inPut(struct Book *book); void inPut(struct Book *book){ printf("請輸入書名:"); fflush(stdout); scanf("%s",book -> title); printf("請輸入作者:"); fflush(stdout); scanf("%s",book -> author); printf("請輸入售價:"); fflush(stdout); scanf("%f",&book -> price); printf("請輸入出版日期(yyyy-mm-dd):"); fflush(stdout); scanf("%d-%d-%d",&book -> date.year,&book -> date.month,&book -> date.day); printf("&book = %p:\n",&book); printf("book = %p:\n",book); printf("請輸入出版社:"); fflush(stdout); scanf("%s",book -> publisher); } int main () { struct Book book1; printf("=============輸入第一本書的信息============\n"); inPut(&book1); printf("=============打印第一本書的信息============\n"); printf("第一本書的作者:%s\n",book1.author); printf("第一本書的日期:%d-%d-%d\n",book1.date.year,book1.date.month,book1.date.day); printf("第一本書的價格:%f\n",book1.price); printf("第一本書的出版社:%s\n",book1.publisher); printf("第一本書的書名:%s\n",book1.title); return 0; }
運行結果:
使用malloc給結構體申請空間:
#include <stdio.h> #include <stdlib.h> struct Date{ int year; int month; int day; }; struct Book{ char title[128]; char author[40]; char publisher[40]; float price; struct Date date; }; void inPut(struct Book *book); void inPut(struct Book *book){ printf("請輸入書名:"); fflush(stdout); scanf("%s",book -> title); printf("請輸入作者:"); fflush(stdout); scanf("%s",book -> author); printf("請輸入售價:"); fflush(stdout); scanf("%f",&book -> price); printf("請輸入出版日期(yyyy-mm-dd):"); fflush(stdout); scanf("%d-%d-%d",&book -> date.year,&book -> date.month,&book -> date.day); printf("&book = %p:\n",&book); printf("book = %p:\n",book); printf("請輸入出版社:"); fflush(stdout); scanf("%s",book -> publisher); } int main () { struct Book *book1; book1 = (struct Book *)malloc(sizeof(struct Book)); if(book1 == NULL){ exit(1); } printf("=============輸入第一本書的信息============\n"); inPut(book1); printf("=============打印第一本書的信息============\n"); printf("第一本書的作者:%s\n",book1 -> author); printf("第一本書的日期:%d-%d-%d\n",book1 -> date.year,book1 -> date.month,book1 -> date.day); printf("第一本書的價格:%f\n",book1 -> price); printf("第一本書的出版社:%s\n",book1 -> publisher); printf("第一本書的書名:%s\n",book1 -> title); free(book1); return 0; }
運行結果:
單鏈表
#include <stdio.h> #include <stdlib.h> struct Book{ char author[40]; struct Book *next; }; void inPut(struct Book *book); void inPut(struct Book *book){ printf("請輸入作者:"); fflush(stdout); scanf("%s",book -> author); } void addBook(struct Book **library); void addBook(struct Book **library){ struct Book *book1, *tmp; book1 = (struct Book *)malloc(sizeof(struct Book)); if(book1 == NULL){ exit(1); } inPut(book1); if(*library != NULL){ tmp = *library; *library = book1; book1->next = tmp; } else { *library = book1; book1->next = NULL; } } int main () { struct Book *library, *book; library->next = NULL; library = NULL; // 不知道爲什麼這邊或不清空會出現一個Q addBook(&library); addBook(&library); book = library; while(book != NULL){ printf("第一本書的作者:%s\n",book->author); book = book->next; } return 0; }
運行結果:
刪除單鏈表節點
#include <stdio.h> #include <stdlib.h> struct Node{ int a; struct Node *next; }; void insertNode(struct Node **node,int input); void insertNode(struct Node **node,int input){ struct Node *previous; // 比input小的節點 struct Node *current; // 當前節點(比input大的節點) struct Node *new; // 新加入的指針 current = *node; previous = NULL; while(current != NULL && current->a < input){ previous = current; current = current->next; } new = (struct Node *)malloc(sizeof(struct Node)); if(new == NULL){ exit(1); } new->a = input; new->next = current; if(previous == NULL){ *node = new; }else{ previous->next = new; } } void deleteNode(struct Node **node ,int input); void deleteNode(struct Node **node ,int input){ struct Node *previous; // 比input小的節點 struct Node *current; // 當前節點(比input大的節點) current = *node; previous = NULL; while(current !=NULL && current->a != input){ previous = current; current = current ->next; } if(current == NULL){ printf("沒有找到匹配的節點"); return; }else{ if(previous == NULL){ *node = current->next; }else{ previous->next = current->next; } } free(current); } void printNode(struct Node **node); void printNode(struct Node **node){ struct Node *current; current = *node; while(current != NULL ){ printf("%d ",current->a); current = current->next; } printf("\n"); } int main(void){ struct Node *head = NULL; int input; while(1){ printf("請輸入一個整數:"); fflush(stdout); scanf("%d",&input); if(input == -1){ break; } insertNode(&head,input); printNode(&head); } while(1){ printf("請輸入一個需要刪除整數:"); fflush(stdout); scanf("%d",&input); if(input == -1){ break; } deleteNode(&head,input); printNode(&head); } return 0; }
運行結果:
typedef 關鍵字
#include <stdio.h> typedef int integer; // 將int 取成integer別名 int main(void){ integer a = 520; int b = 520; printf("a= %d\n",a); printf("b= %d\n",b); printf(""); return 0; }
運行結果:
給結構體取別名:
#include <stdio.h> #include <stdlib.h> typedef struct Date { int year; int month; int date; } DATE; int main(void){ DATE *date = (DATE *)malloc(sizeof(DATE)); date->year = 2017; date->month = 12; date->date = 31; printf("%d-%d-%d\n",date->year,date->month,date->date); return 0; }
運行結果:
案例3
#include <stdio.h> typedef int (*PTR_TO_ARRAY)[3]; int main(void){ int array[] = {1,2,3}; PTR_TO_ARRAY ptrToArray = &array; for (int i = 0; i < 3; ++i) { printf("%d\n",(*ptrToArray)[i]); } return 0; }
運行結果:
共同體
共用體的對個成員使用同一個內存開始地址。 所以共用體,同時只能由一個成員被使用。
#include <stdio.h> #include <string.h> union Test{ int i; double pi; char str[6]; }; int main(void){ union Test test; test.i = 520; test.pi = 3.14; strcpy(test.str,"Hello"); printf("address of test.1 : %p\n",&test.i); printf("address of test.1 : %p\n",&test.pi); printf("address of test.1 : %p\n",test.str); return 0; }
運行結果:
枚舉類型
#include <stdio.h> int main(){ enum week{ Mon = 1, Tues=2, Wed=3, Thurs=4, Fri=5, Sat=6, Sun=7 } day; scanf("%d", &day); switch(day){ case Mon: puts("Monday"); break; case Tues: puts("Tuesday"); break; case Wed: puts("Wednesday"); break; case Thurs: puts("Thursday"); break; case Fri: puts("Friday"); break; case Sat: puts("Saturday"); break; case Sun: puts("Sunday"); break; default: puts("Error!"); } return 0; }
運行結果:
位域
#include <stdio.h> int main(){ struct Test{ unsigned int a:1; unsigned int b:1; unsigned int c:2; }; struct Test test; test.a = 0; test.b = 1; test.c = 2; printf("a = %d; b = %d;c = %d;\n",test.a,test.b,test.c); printf("size %d", sizeof(struct Test)); return 0; }
運行結果:
位域不能超過32位。 不能存比設置大的值。 位域最好使用int 。
位邏輯運算
#include <stdio.h> int main(){ int a = 0xFFFFFFFF; int mask = 0xABCDEF01; printf("0x%X\n" ,~a); printf("0x%X\n" ,mask^a); printf("0x%X\n" ,mask|a); printf("0x%X\n" ,mask&a); return 0; }
運行結果:
c語言的邏輯運算符:
文件讀寫
#include <stdio.h> #include <stdlib.h> int main(){ FILE *fp1; // 讀取的文件。 FILE *fp2; // 寫入的文件 int ch; if((fp1 = fopen("hello.txt","r")) == NULL){ printf("打開文件失敗!"); exit(EXIT_FAILURE); } if((fp2 = fopen("write.txt","a")) == NULL){ printf("打開文件失敗!"); exit(EXIT_FAILURE); } while((ch = fgetc(fp1)) != EOF){ // 判斷讀取的文件是否已經沒有數據了,EOF表示讀取失敗了 fputc(ch,fp2); } fclose(fp1); fclose(fp2); return 0; }
運行結果:
hello.txt 的內容會複製到write文件夾裏面。
文件讀寫案例2:
#include <stdio.h> #include <stdlib.h> int main(){ FILE *fp; // 寫入的文件 char buffer[1024]; int ch; if((fp = fopen("mode.txt","w")) == NULL){ printf("打開文件失敗!"); exit(EXIT_FAILURE); } fputs("你好!\n",fp); fputs("我很好!",fp); fclose(fp); // 寫入文件,關閉流 if((fp = fopen("mode.txt","r")) == NULL){ printf("打開文件失敗!"); exit(EXIT_FAILURE); } while(!(feof(fp))){ // 判斷讀取的文件是否已經沒有數據了,EOF表示讀取失敗了 fgets(buffer,1024,fp); printf("buffer = %s",buffer); } fclose(fp); return 0; }
運行結果:
文件讀取案例3:
#include <stdio.h> #include <stdlib.h> #include <time.h> int main(){ FILE *fp; // 寫入的文件 struct tm *p; time_t t; time(&t); p = localtime(&t); if((fp = fopen("date.txt","w")) == NULL){ printf("打開文件失敗!"); exit(EXIT_FAILURE); } fprintf(fp,"%d-%d-%d",1900+p->tm_year,1+p->tm_mon,p->tm_mday); fclose(fp); int year,month,day; if((fp = fopen("date.txt","r")) == NULL){ printf("打開文件失敗!"); exit(EXIT_FAILURE); } fscanf(fp,"%d-%d-%d",&year,&month,&day); printf("%d-%d-%d",year,month,day); fclose(fp); return 0; }
運行結果:
文件讀取案例4:(fwrite和fread)
#include <stdio.h> #include <stdlib.h> #include <string.h> struct Date{ int year; int month; int day; }; struct Book{ char title[128]; char author[40]; char publisher[40]; struct Date date; }; int main(){ FILE *fp; // 寫入的文件 struct Book *book_write, *book_read; book_write = (struct Book *)malloc(sizeof(struct Book)); book_read = (struct Book *)malloc(sizeof(struct Book)); if(book_write == NULL || book_read == NULL){ printf("分配內存失敗!"); exit(1); } strcpy(book_write->title,"good good study"); strcpy(book_write->author,"lili"); strcpy(book_write->publisher,"bei jin"); book_write->date.year = 2020; book_write->date.month = 1; book_write->date.day = 1; if((fp = fopen("struct.txt","wb")) == NULL){ printf("打開文件失敗!"); exit(EXIT_FAILURE); } fwrite(book_write, sizeof(struct Book),1,fp); fclose(fp); if((fp = fopen("struct.txt","r")) == NULL){ printf("打開文件失敗!"); exit(EXIT_FAILURE); } fread(book_read, sizeof(struct Book),1,fp); fclose(fp); printf("第一本書的作者:%s\n",book_read -> author); printf("第一本書的日期:%d-%d-%d\n",book_read -> date.year,book_read -> date.month,book_read -> date.day); printf("第一本書的出版社:%s\n",book_read -> publisher); printf("第一本書的書名:%s\n",book_read -> title); return 0; }
運行結果:
文件讀取案例5:(fseek 函數)切換讀取開始位置
#include <stdio.h> #include <stdlib.h> #define N 2 struct Stu{ char name[40]; int age; }stu[N] ,sb; int main(){ FILE *fp; // 寫入的文件 if((fp = fopen("source.txt","w")) == NULL){ printf("打開文件失敗!"); exit(EXIT_FAILURE); } printf("請輸入學生信息(姓名和年齡)"); fflush(stdout); for (int i = 0; i < N; ++i) { scanf("%s %d",&stu[i].name,&stu[i].age); } fwrite(stu, sizeof(struct Stu),N,fp); fclose(fp); if((fp = fopen("source.txt","rb")) == NULL){ printf("打開文件失敗!"); exit(EXIT_FAILURE); } fseek(fp, sizeof(struct Stu),SEEK_SET); fread(&sb, sizeof(struct Stu),1,fp); fclose(fp); printf("姓名:%s,年齡:%d。\n",sb.name,sb.age); return 0; }
運行結果:
文件讀取案例6:錯誤輸出
#include <stdio.h> #include <stdlib.h> int main(){ FILE *fp; // 寫入的文件 int ch; if((fp = fopen("hello.txt","r")) == NULL){ fputs("打開文件失敗!",stderr); exit(EXIT_FAILURE); } while(1){ ch = fgetc(fp); if(feof(fp)){ break; } putchar(ch); } fputc('c',fp); if(ferror(fp)){ fputs("出錯了",stderr); } clearerr(fp); // 清除錯誤指示器和eof指示器 fclose(fp); return 0; }
運行結果:
文件讀取案例7:錯誤信息打印
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(){ FILE *fp; // 寫入的文件 if((fp = fopen("bucunzai.txt","r")) == NULL){ printf("錯誤代碼:%d\n", errno); perror("perror打印錯誤信息"); fprintf(stderr, "fprintf打印標準錯誤輸出:%s\n", strerror(errno)); printf("printf打印標準輸出:%s\n", strerror(errno)); exit(EXIT_FAILURE); } fclose(fp); return 0; }
運行結果:
文件讀取案例8:刷新流
#include <stdio.h> #include <string.h> int main(){ char buf[1024]; memset(buf,'\0',sizeof(buf)); setvbuf(stdout,buf,_IOFBF,1024); fprintf(stdout,"welcome to bbc\n"); fflush(stdout); // 刷新流 fprintf(stdout,"welcome to abb\n"); getchar(); // 阻塞,需要輸入一個字符纔可以執行 fflush(stdout); // 刷新流 return 0; }
運行結果: