1. 程式人生 > 其它 >C Primer Plus 學習筆記 -- 前六章

C Primer Plus 學習筆記 -- 前六章

記錄自己學習C Primer Plus的學習筆記

第一章

C語言高效在於C語言通常是組合語言才具有的微調控能力設計的一系列內部指令

C不是面向物件程式設計

編譯器把原始碼轉化成中間程式碼,連結器把中間程式碼和其他程式碼合併,生成可執行檔案

第二章

main函式總是第一個被呼叫的函式

include前處理器指令

宣告,所有變數都必須先宣告才能使用,最初的規則規則變數宣告需在塊的頂部

C語言通過賦值運算子而不是賦值語句來完成賦值操作,聽起來很彆扭,賦值語句其實就是賦值表示式+分號

第三章

由於現在16位機已經很少了,故不再記憶16位機相關資料型別

char、short、int、long在32位機中為1、2、4、4,在64位中為1、2、4、8,float為4,double為8

unsigned int也是4位元組,用%u輸出

C語言中有單引號和雙引號之分,單引號表示一個字元,雙引號表示字串

輸出時,可以前後數量不匹配,這樣未輸出的就是記憶體任意數

#include <stdio.h>
int main(){
    int ten = 10;
    printf("%d minus %d is %d",ten);
    return 0;
}

10 minus 6422404 is 4201008

在使用long型別時,賦值時若數字太小,則需要在數字之後新增l或者L

下面程式中,sizeof標準輸出應該時%zd,但是也可以%d

#include<stdio.h>
int main(){
    long n = 1;
    long long m = 2l;
    printf("n:%ld\n",n);
    printf("%d\n",sizeof(n));
    printf("m:%ld\n",m);
    printf("%d\n",sizeof(m));
    return 0;
}

n:1
4
m:2
8

使用響鈴時,需加上windows.h標頭檔案

#include<stdio.h>
#include<windows.h>
int main(void){
    Beep(500,2000);
    printf("\a");
    return 0;
}

可移植型別,看了感覺沒什麼很大用,以後遇到了再看

C語言標準的布林型別是_Bool,但是也可以用新增標頭檔案的方法使用bool

//匯入 stdbool.h 來使用布林型別
#include <stdbool.h>
#include <stdio.h>

//計算n!,n的值在main中定義
int main(void)
{
    int n = 10;    //計算疊乘數
    int sum = 1; //用來存放疊乘的結果
    bool flag = false;    //疊乘標記
    
    int num = n;    //迴圈次數
    while( !flag )
    {
        sum = sum * (num--);
        //當num=1時結束迴圈
        if( num == 1)
        {
            flag = true;
        }
    }
    printf ("%d的疊乘值為 %d \n", n, sum);
    return 0;
}

10的疊乘值為 3628800 

第四章

C語言沒有專門的字串,使用字元陣列或者指標

字元陣列末尾位置使用字元\0,用\0來標記字串的結束

/* praisel.c -- 使用不同型別的字串 */
#include <stdio.h>
#define PRAISE "You are an extraodinary being."
int main(){
    char name[40];
    printf("What's your name?");
    scanf("%s",name);
    printf("Hello, %s. %s\n",name,PRAISE);

    return 0;
}

字串"c"和字元"c"的區別在於字串"c"實際上是由兩個字元組成:"c"+空字元\0

使用strlen需要新增string.h標頭檔案

使用#define預處理指令來進行自定義,也可用const修飾符建立符號常變數
注意define定義的是常量,const定義常變數
const常變數不能簡單修改,但是可以通過修改指標的方式進行修改

讀取字串陣列時,遇到空白則停止
用strlen算出來的長度比用sizeof算出來的長度少1

格式化輸出的時候,%m.n表示小數點後輸出n位,這是精度,m表示共m位,如果m<n則作罷,m>n則左邊用空格代替

scanf對於除%c外的型別,會自動輸入除空格外的字元。對於%c,如果在%c之前加空格,則會從第1個非空字元開始讀取,如果%c之前不加空格,則從輸入的第1個字元開始讀取

printf和scanf的*修飾符
printf的修飾符來代替欄位寬度
scanf的
主要是跳過輸入項

#include<stdio.h>
int main(void){
    unsigned width,precision;
    int number = 256;
    double weight = 242.5;

    printf("Enter a field width:\n");
    scanf("%d",&width);
    printf("The Number is %*d:\n",width,number);
    printf("Now enter a width and a precision:\n");
    scanf("%d %d",&width,&precision);
    printf("Weight = %*.*f\n",width,precision,weight);
    printf("Done!\n");
    return 0;
}

Enter a field width:
6
The Number is    256:
Now enter a width and a precision:
8 3
Weight =  242.500
Done!

第五章

C語言可以三重賦值

其實python也可以,並且python可以用如下賦值方法

a,b = 3,4
a,b = (3,4)

C99規定截斷趨零,求模時,前者為正則為正,前者為負則為負

#include<stdio.h>
int main(void){
    printf("%d\n",11%5);
    printf("%d\n",11%-5);
    printf("%d\n",-11%5);
    printf("%d\n",-11%-5);
    return 0;
}

1
1
-1
-1

遞增運算子有很高的結合優先順序,只有圓括號優先順序比他們高,但不建議這樣做

#include<stdio.h>
int main(){
    int a = 3;
    int b = 4;
    printf("3*++4:%d\n",a*++b);
    printf("b:%d\n",b);
    printf("3*5++:%d\n",a*b++);
    printf("b:%d\n",b);
    return 0;
}

3*++4:15
b:5
3*4++:15
b:6

語句和表示式不一樣,語句是C程式的基本構建塊,一條語句相當於一條完整的計算機指令

副作用:副作用是對資料物件或檔案的修改,如states=50,副作用是將變數的值設定為50

序列點:程式執行的點,各種運算物件的改變必須在執行下一條語句之前完成

第六章

scanf讀取一個輸入的值,並返回0或者1

注意如果while之後可以接一句語句,或者直接接分號,或者接花括號

#include<stdio.h>
int main(){
    int n = 0;
    while(n++<3);
        printf("n is %d\n",n);
    printf("That's all this program dose.\n");
    return 0;
}

n is 4
That's all this program dose.

計算機中數字往往不精確,不只是C,所以常常用fabs來判斷是否相等,如1/3再乘以3很可能為0.999999

#include<stdio.h>
#include<math.h>
int main(){
    printf("%d\n",fabs(3.14159-3.14)<0.0001);
    printf("%d\n",fabs(3.14159-3.1416)<0.0001);
    return 0;
}

0
1

C語言中真值為除0之外的數,其實python也一樣

i = -2
while i:
    print("True")
    i += 1
    if i > 3:
        break
True
True

使用==運算子時,最好左邊為常量,右邊為變數,這樣更清晰

#include<stdio.h>
int main(){
    long sum = 0L;
    long num;
    int status;
    printf("enter an integer to be summed ");
    printf("(q to quit)");
    status = scanf("%ld",&num);
    while(status=1){
        sum = sum + num;
        printf("enter next integer(q to quit):");
        status = scanf("%ld",&num);
    }
}

這裡會一直輸出的原因在於,迴圈中輸入非數字時,如輸入q,此時不是ld型別,則讀取失敗,把q放入輸入佇列,下次繼續讀取。聽著很抽象,再看下面這個例子

#include <stdio.h>
int main()
{
    int m;
    int n;
    char d;
    char e;
    
    printf("m:%d\n", m);
    printf("n:%d\n", n);
    printf("d:%d\n", d);
    printf("e:%d\n", e);
    printf("***********\n");
    scanf("%d", &m);
    scanf("%d", &n);
    scanf("%c", &d);
    scanf("%c", &e);

    printf("m:%d\n", m);
    printf("n:%d\n", n);
    printf("d:%c\n", d);
    printf("e:%c\n", e);
    return 0;
}
m:2691072
n:4199120
d:0
e:64
***********
abcd
m:2691072
n:4199120
d:a
e:b
m:3588096
n:4199120
d:0
e:64
***********
a1cd
m:3588096
n:4199120
d:a
e:1
m:2621440
n:4199120
d:0
e:64
***********
1a23
m:1
n:4199120
d:a
e:2

這個時輸入輸出流,後面會詳細講?

C中布林型別,C99為_Bool,並且可以使用stdbool.h標頭檔案來直接使用truefalse

字串在字元陣列的末尾為\0