《C言語 基礎知識》入門案例

前言

爲了更加學習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 = &num;
    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;
    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 = &square;

    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 = &square;

    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 &sub;
    }
}

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;
}

運行結果:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章