博客 / 詳情

返回

數據與C

變量與常量

為了能夠更加方便的使用數據,程序員會將在程序運行期間會改變或賦值的數據使用變量進行保存。常量則是預先定義好,在程序運行期間不會改變的固定值

變量和常量就好像是一個盒子,可以用來裝東西(數據)。在計算機中,數據是存放在內存中的,存放數據的內存空間程序員為了方便以後的使用,都會起一個好記的名字。這個名稱也由字母、數字和下劃線組成,必須要以字母和下劃線開頭。由於C語言是對大小寫敏感的,所以大寫字母和小寫字母是不同的,也就是變量名abc和Abc是兩個不同的變量。

數據類型

不同的數據類型有不同的含義,有的數據類型表示整數,有的表示字符,有的表示浮點數。常量可以是任何的數據類型,通過常量的值識別(100是整數,123.45是浮點數)。而變量則需要指定數據類型。在C語言中有很多種數據類型,從最初的K&R給出的7個數據類型關鍵字,再到C90添加的2個新的關鍵字,到最後的C99添加的3個關鍵字

最初K&R給出的關鍵字 C90標準添加的關鍵字 C99標準添加的關鍵字
int signed _Bool
long void _Complex
short _Imaginary
unsigned
char
float
double

int、long、short、unsigned和C90新添加的signed關鍵字用於表示整數類型,unsigned表示無符號數,signed則表示有符號數,整數類型的例子:unsigned short int 和 long long int

char關鍵字用於存放字母和其他字符(如:$、%等),char也可以用來表示較小的整數

float、double和long double表示浮點數

_Bool表示布爾類型(true或false)

_Complex和_Imaginary分別表示複數和虛數

存儲大小

不同的數據類型可以存放的數據大小是不同的,能夠存放的數據越多,值越大。

數據類型 存儲大小
char 1字節
int 2或4字節()
short 2字節
long 4字節
float 4字節
double 8字節
long double 16字節

在C語言中,可以通過sizeof運算符查看數據類型存儲字節的大小

#include<stdio.h>

int main()
{
    printf("char 的存儲大小: %d\n", sizeof(char));
    printf("short 的存儲大小: %d\n", sizeof(short));
    printf("int 的存儲大小: %d\n", sizeof(int));
    printf("long 的存儲大小: %d\n", sizeof(long));
    printf("float 的存儲大小: %d\n", sizeof(float));
    printf("double 的存儲大小: %d\n", sizeof(double));
    printf("long double 的存儲大小: %d\n", sizeof(long double));

    return 0;
}

運行結果:

這裏使用到的printf()函數,後面會進行講解,目前只需要知道printf()是用來打印內容到屏幕上的就可以了。

變量的定義

C語言提供了很多種數據類型,在定義變量時需要指定變量的數據類型,如整數可以使用int類型,小數可以使用float類型等,下面將開始介紹如何定義變量。

定義變量

定義變量的語法:數據類型 變量名;

舉個例子,下面的程序用於計算兩個整數的和

#include<stdio.h>

int main()
{
    int num1;   //定義一個變量num1,用於存放第一個數
    int num2;   //定義一個變量num2,用於存放第二個數
    int sum;    //定義一個變量sum,用於存放兩個數的和
    
    num1 = 100;        //將整數100賦值給變量num1
    num2 = 200;
    sum = num1 + num2;  //計算num1與num2相加,並將值賦值給sum變量

    printf("num1 + num2 = %d\n", sum);      // 將sum的值打印到屏幕

    return 0;
}

運行結果:

在聲明num1和num2變量時,並沒有給它們提供初始值。num1和num2是通過後面的 num1 = 100;num2 = 200; 獲取到值的,這種行為稱為初始化。初始化就是給變量一個初始值。

定義變量時初始化

在上面的例子中,定義變量與給初始化變量是分成兩步的,也可以將這兩步合併在一起,將程序修改後如下:

#include<stdio.h>

int main()
{
    int num1 = 100;   //定義變量num1並將100賦值給num1
    int num2 = 200;
    int sum = num1 + num2;   //num1與num2相加後的結果賦值給sum變量

    printf("num1 + num2 = %d\n", sum);      // 將sum的值打印到屏幕

    return 0;
}

連續定義多個變量

修改後的程序比之前的簡潔了,接着我們發現num1和num2的數據類型是相同的,都是int類型,那麼這兩個變量就可以一起定義,還是上面的例子,修改後如下:

#include<stdio.h>

int main()
{
    int num1 = 100, num2 = 200;     //同時聲明num1和num2並賦值
    int sum = num1 + num2;   //num1與num2相加後的結果賦值給sum變量

    printf("num1 + num2 = %d\n", sum);      // 將sum的值打印到屏幕

    return 0;
}

需要注意的是,為了不讓人誤會在同時定義多個變量時,有的變量不需要初始化,而有的變量需要進行初始化。那麼不建議寫在一起,建議分開定義,如int num1, num2= 200; 這樣寫很容易讓人誤以為num1和num2的值都是200,所以不建議這麼寫,當然這麼寫是不會報錯的。

常量的定義

通過一個例子開始講解常量的使用,下面的程序的作用是計算圓的周長和麪積:

#include<stdio.h>

int main(void)
{
    float pi = 3.14159;     //圓周率
    int r = 5;              //圓的半徑

    float area = pi * r * r;        //計算圓的面積
    float circum = 2 * pi * r;      //計算圓的周長

    printf("半徑為 %d 的圓面積是: %.2f, 周長是: %.2f", r, area, circum);

    return 0;
}

通過上面的例子可以知道變量也可以當做常量來使用,但是在實際使用的時候不建議這麼使用,因為在程序運行過程中有可能會將定義的變量改變,變量並非不可改變的。那有沒有更好的定義常量的方法呢?有,這就需要使用預處理語句定義一個常量,這樣定義的常量也被稱為符號常量。語法是:#define NAME value

使用預處理語句,修改上面的例子:

#include<stdio.h>
#define PI 3.14159     //使用預處理語句定義圓周率


int main(void)
{
    int r = 5;              //圓的半徑

    float area = PI * r * r;        //計算圓的面積
    float circum = 2 * PI * r;      //計算圓的周長

    printf("半徑為 %d 的圓面積是: %.2f, 周長是: %.2f", r, area, circum);

    return 0;
}

預處理語句的作用是在編譯的時候將PI替換為3.14159,這樣就達到了常量的作用了。預處理語句一定要寫在頂部,並且PI和3.14159之間是沒有等號和結束時也沒有分號的。前面也説了預處理語句是在編譯時替換掉值,如果有了等號和分號,那麼等號和分號也會變成要替換的值了。

還有一種方法是使用限定符 const 將變量限定為只讀,修改上面的例子如下:

#include<stdio.h>

int main(void)
{
    const float pi = 3.14159;     //使用限定符const,定義常量圓周率
    int r = 5;                    //圓的半徑

    float area = pi * r * r;        //計算圓的面積
    float circum = 2 * pi * r;      //計算圓的周長

    printf("半徑為 %d 的圓面積是: %.2f, 周長是: %.2f", r, area, circum);

    return 0;
}

使用 const 限定符定義的變量pi可以使用,可以使用 printf() 打印值,但就是無法修改值。另外需要注意的是使用 const 限定符定義的是變量,不是常量。

輸入輸出

輸出

在C語言中,通過printf()將內容輸出到屏幕上,printf()也被稱為格式化輸出,可以讓變量以某種格式輸出到屏幕上,如 %d為以整數的形式顯示,%f以浮點數的形式顯示,下表列出了一些轉換説明和各自對應的輸出類型:

轉換説明 輸出
%a 浮點數、十六進制和p記數法
%A 浮點數、十六進制和p記數法
%c 單個字符
%d 有符號十進制整數
%e 浮點數,e記數法
%E 浮點數,e記數法
%f 浮點數,十進制記數法
%g 根據值的不同,自動選擇%f或%e。%e格式用於指數小於-4或者大於或等於精度時
%G 根據值的不同,自動選擇%f或%E。%E格式用於指數小於-4或者大於或等於精度時
%i 有符號十進制整數(與%d相同)
%o 無符號八進制整數
%p 指針
%s 字符串
%u 無符號十進制整數
%x 無符號十六進制整數,使用十六進制數0f
%X 無符號十六進制整數,使用十六進制數0F
%% 打印一個百分號

一開始不需要全部都記住,只需要記住幾個常用的(如:%d,%f,%c)即可,其他的用到在看就可以了,用的多了就記住了。下面的例子是將一個整數以八進制和十六進制的形式顯示:

#include<stdio.h>

int main(void)
{
    int num = 100; 

    printf("100 的八進制為 %o\n", num);        //顯示num的八進制
    printf("100 的八進制為 %#o\n", num);        //顯示num的八進制時,並在前面加上前綴
    printf("100 的十六進制為 %x\n", num);        //顯示num的十六進制
    printf("100 的十六進制為 %#x\n", num);    //顯示num的十六進制,並在前面加上前綴
    return 0;
}

運行結果:

可以通過printf()函數配合%o和%x打印出數值的八進制形式和十六進制形式。#只是為了顯示前綴,八進制以0開頭,十六進制以0x開頭

有的讀者可能不太瞭解什麼是八進制和十六進制,那就簡單的介紹一下。我們日常説的10,100,123等數字,都是十進制,可以發現這些數字都是逢十進一,而八進制和十六進制同理,八進制就是逢八進一,十六進制是逢十六進一。有的讀者就會問了,逢十六進一?那要怎麼表示十以上的數呀?十六進制由1到9和a到f(也可以是A到F)組成,沒錯,a到f分別表示10到15。

參數與陷阱

在使用printf()scanf() 時需要確保轉換説明的數量、類型與後面的參數數量、類型匹配。由於 printf()scanf() 的參數是可變的,所以無法檢查出參數的個數和類型是否正確。

那如果參數個數不匹配會怎樣呢?

#include<stdio.h>

int main(void)
{
    int num1 = 1;
    float num2 = 1.23;

    printf("%d %d %d\n", num1, num1, num1, num1);   //參數太多
    printf("%d %d %d\n", num1);   //參數太少
    printf("%d\n", num2);           //類型不匹配


    return 0;
}

運行結果:

當使用%d打印一個浮點數時,不會將這個浮點數轉換為int類型。在不同的平台下,缺少參數或參數類型不匹配導致的結果會不相同。

輸入

在前面的兩個數相加的例子中,兩個相加的數是預先就設置好的,當要計算其他整數相加時,需要修改源文件並生成新的可執行文件,這就很麻煩,這是就可以讓用户輸入要進行計算的兩個整數。

要想獲取用户的輸入可以使用scanf()進行接收,使用的方法與printf()相似,%d表示要接收整數,%f表示要接收一個浮點數。

修改程序:

#include<stdio.h>

int main(void)
{
    int num1, num2;     //同時聲明num1和num2
    scanf("%d %d", &num1, &num2);       //獲取用户輸入的num1和num2的值
    int sum = num1 + num2;   //num1與num2相加後的結果賦值給sum變量

    printf("num1 + num2 = %d\n", sum);      // 將sum的值打印到屏幕

    return 0;
}

運行結果:

運行完程序,應該可以發現如果這是給程序員自己使用,那當然沒有任何問題,但是給其他人使用,會出現不知道要幹嘛的情況。所以應該在程序接收用户輸入之前,告訴用户要做什麼,再次修改程序:

#include<stdio.h>

int main(void)
{
    int num1, num2;     //同時聲明num1和num2
    printf("請輸入兩個需要相加的整數(例:12 34):");    //提示用户輸入兩個整數
    scanf("%d %d", &num1, &num2);       //獲取用户輸入的num1和num2的值
    int sum = num1 + num2;               //num1與num2相加後的結果賦值給sum變量

    printf("num1 + num2 = %d\n", sum);  // 將sum的值打印到屏幕

    return 0;
}

運行結果:

細心的讀者會發現在num1和num2的前面有一個&符號,那這個&符號表示的是什麼意思呢?&符號表示獲取地址,整個語句就是將獲取到的整數放入到num1和num2的地址中。

當讀取的是基本的數據類型的值時需要使用&符號,而讀取的是字符串時,不要使用&符號。

整數溢出

當一個整數類型超出了它能表示的最大值會出現溢出,通過一個例子觀察溢出後的結果

#include<stdio.h>

int main(void)
{
    int i = 2147483647;     //定義一個有符號整數類型的變量i並初始化為最大值
    unsigned int j = 4294967295;       //定義一個無符號整數類型的變量j並初始化為最大值

    printf("%d %d %d\n", i, i+1, i+2);
    printf("%u %u %u\n", j, j+1, j+2);
    return 0;
}

運行結果:

通過觀察可以發現當一個數超過自身能夠表示的最大值時,會從最小值開始。當發生溢出時系統沒有告訴用户,所以在編程時需要注意。

char類型

char類型用於存放字符(如:字母或標點符號),但char其實是整數類型,因為char實際上保存的是整數,而不是字符。有的讀者就會有疑問了,存儲整數,那要怎麼知道是哪個字符呢?在計算機中使用數字編碼處理字符,即使用整數表示字符,在ASCII編碼中65表示大寫字母"A",標準的ASCII的範圍是0~127,完全可以使用char類型進行存儲

聲明char類型變量

char類型的變量在賦值時,值需要使用單引號括起來,如:char ch = 'A'; ,而不能是 char ch = A; 。如果沒有被單引號括起來,此時A表示一個變量名,而不是字符A。

char類型也可以直接保存整數,如 char ch = 65; ,但是不建議這樣使用,這樣使用需要系統支持ASCII碼,最好還是使用 ‘A’ 替換 65。

舉個例子

用户輸入一個字符,將這個字符對應的ASCII碼打印在屏幕上:

#include<stdio.h>

int main(void)
{
    char ch;    //定義變量ch,用於接收用户輸入

    printf("請輸入一個字符(如:A):");
    scanf("%c", &ch);       //接收用户輸入的字符
    printf("%c 對應的整數為 %d\n", ch, ch);
    return 0;
}

運行結果:

轉義字符

使用特殊的符號序列表示一些特殊的字符,這些符號序列就叫做轉義序列,下表列出了轉義序列及其含義

轉義序列 含義
\a 警報(ANSI C)
\b 退格
\f 換頁
\n 換行
\r 回車
\t 水平製表符(相當於tab鍵)
\v 垂直製表符
\\ 反斜槓()
\' 單引號
\" 雙引號
? 問號
\0oo 八進制值(oo必須是有效八進制數)
\xhh 十六進制值(hh必須是有效十六進制數)

通過一個例子更好的理解轉義字符:

#include<stdio.h>

int main(void)
{
    float salary;

    printf("\aEnter your desired monthly salary:");
    printf(" $_______\b\b\b\b\b\b\b");
    scanf("%f", &salary);
    printf("\n\t$%.2f a month is $%.2f a year.", salary, salary * 12.0);
    printf("\rGee!\n");
    return 0;
}

運行結果:

解析:

在程序的第7行 printf("\aEnter your desired monthly salary:"); 中的 \a 會發出警報的聲音(能否發出警報取決於硬件,有可能不會發出警報)

接着第8行的 printf(" $_______\b\b\b\b\b\b\b"); 先將$_______打印出來呢,接着使用 \b 移動光標,使光標緊跟$符

在第10行的 printf("\n\t$%.2f a month is $%.2f a year.", salary, salary * 12.0); 首先是 \n 進行換行,接着是製表符 \t 使後面的內容縮進。光標停留在最後的點那裏(.),如下圖:

在第11行的 printf("\rGee!\n"); \r 將光標移動到當前行是起始位置,再打印內容,最後的 \n 換行

reference

《C Primer Plus》(第六版)

大話C語言變量和數據類型---C語言中文網

C語言轉義字符---C語言中文網

C 數據類型---菜鳥教程

C 變量---菜鳥教程

C 常量---菜鳥教程

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.