C語言歸納一

一、注意點

1.字符串輸出

#include<stdio.h>
int main()
{
    puts("C語  言 中文網");
    puts("C語言
    中文網");
    return 0;
}

第 5~6 行代碼是錯誤的,字符串必須在一行內結束,不能換行。

2.控制檯顏色設置

WORDwindows.h中定義,等同於unsigned short,使用低4位表示文字(前景)顏色,高4位表示文字背景顏色,所以它的取值爲xx。x爲一位16進制數,即0~F都可以使用,可以隨意組合。

0~F 分別代表的顏色如下:

0 = 黑色    8 = 灰色    1 = 淡藍      9 = 藍色
2 = 淡綠    A = 綠色    3 = 湖藍      B = 淡淺綠  
C = 紅色    4 = 淡紅    5 = 紫色      D = 淡紫  
6 = 黃色    E = 淡黃    7 = 白色      F = 亮白

例如,將背景設置爲淡綠色,文字設置爲紅色:

#include <stdio.h>
#include <windows.h>
int main(){
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hConsole, 0x2C );
    puts("C語言中文網");
    return 0;
}

如果只希望設置文字顏色,背景保持黑色,那麼也可以只給出一位16進制數,例如:

SetConsoleTextAttribute(hConsole, 0xC );  //將文字顏色設置爲紅色
SetConsoleTextAttribute(hConsole, 0xF );  //將文字顏色設置爲白色

3.最簡單的數據類型及數據類型長度

說  明 字符型 短整型 整型 長整型 單精度浮點型 雙精度浮點型 無類型
數據類型 char short int long float double void

在32位環境中,各種數據類型的長度一般如下:

 

說  明 字符型 短整型 整型 長整型 單精度浮點型 雙精度浮點型
數據類型 char short int long float double
長  度 1 2 4 4 4 8

4.如何在字符串中書寫或者輸出長文本

#include <stdio.h>
int main()
{
    puts(
        "C語言中文網,一個學習C語言和C++的網站,他們堅持用工匠的精神來打磨每一套教程。"
        "堅持做好一件事情,做到極致,讓自己感動,讓用戶心動,這就是足以傳世的作品!"
        "C語言中文網的網址是:http://c.biancheng.net"
    );
    return 0;
}

本節講到的 puts、printf,以及後面要講到的 fprintf、fputs 等與字符串輸出有關的函數,都支持這種寫法。

二、整型數據類型的長度及輸出

2.1整型數據類型的長度

對於 32 位的 Windows、Linux 和 Mac OS,short 的長度爲 2 個字節,int 爲 4 個字節,long 也爲 4 個字節。PC和服務器上的 32 位系統佔有率也在慢慢下降,嵌入式系統使用 32 位越來越多。

在 64 位環境下,不同的操作系統會有不同的結果,如下所示:

操作系統 short int long
Win64(64位 Windows) 2 4 4
類Unix系統(包括 Unix、Linux、Mac OS、BSD、Solaris 等) 2 4 8


目前我們使用較多的PC系統爲 Win XP、Win 7、Win 8、Win 10、Mac OS、Linux,在這些系統中,short 和 int 的長度都是固定的,分別爲 2 和 4,大家可以放心使用,只有 long 的長度在 Win64 和類 Unix 系統下會有所不同,使用時要注意移植性。

要注意可以通過sizeof操作符來獲取某個數據類型的長度,即所佔字節大小。

#include <stdio.h>
int main()
{
    short a = 10;
    int b = 100;
   
    int short_length = sizeof(a);
    int int_length = sizeof(b);
    int long_length = sizeof(long);
    int char_length = sizeof(char);
   
    printf("short=%d, int=%d, long=%d, char=%d\n", short_length, int_length, long_length, char_length);
   
    return 0;
}

2.2 不同整型的輸出

使用不同的格式控制符可以輸出不同類型的整數,它們分別是:

  • %hd用來輸出 short int 類型,hd 是 short decimal 的簡寫;
  • %d用來輸出 int 類型,d 是 decimal 的簡寫;
  • %ld用來輸出 long int 類型,ld 是 long decimal 的簡寫。

讀者需要注意,當格式控制符和數據類型不匹配時,編譯器會給出警告,提示程序員可能會存在風險。

2.3 不同類型的整型數據格式的取值範圍與數據溢出情況分析

我們可以計算出所有有符號數的取值範圍(括號內爲假設的長度):

  char short int(4個字節) long(8個字節)
最小值 -27 = -128 -215 = -32,768 ≈ -3.2萬 -231 = -2,147,483,648 ≈ -21億 -263 ≈ -9.22×1018
最大值 27 - 1= 127 215 - 1 = 32,767 ≈ 3.2萬 231 - 1 = 2,147,483,647 ≈ 21億 263 - 1≈ 9.22×1018

若存在數據溢出的情況:

#include <stdio.h>
int main()
{
    unsigned int a = 0x100000000;
    int b = 0xffffffff;
    printf("a=%u, b=%d\n", a, b);
    return 0;
}

運行結果:a=0, b=-1

變量 a 爲 unsigned int 類型,長度爲 4 個字節,能表示的最大值爲 0xFFFFFFFF,而 0x100000000 = 0xFFFFFFFF + 1,佔用33位,已超出 a 所能表示的最大值,所以發生了溢出,導致最高位的 1 被截去,剩下的 32 位都是0。也就是說,a 被存儲到內存後就變成了 0,printf 從內存中讀取到的也是 0。

變量 b 是 int 類型的有符號數,在內存中以補碼的形式存儲。0xffffffff 的數值位的原碼爲 1111 1111 …… 1111 1111,共 32 位,而 int 類型的數值位只有 31 位,所以最高位的 1 會覆蓋符號位,數值位只留下 31 個 1,所以 b 的原碼爲:

1111 1111 …… 1111 1111

這也是 b 在內存中的存儲形式。

當 printf 讀取到 b 時,由於最高位是 1,所以會被判定爲負數,要從補碼轉換爲原碼:

[1111 1111 …… 1111 1111]補
= [1111 1111 …… 1111 1110]反
= [1000 0000 …… 0000 0001]原
= -1

最終 b 的輸出結果爲 -1。

三、二進制數、八進制數和十六進制數的表示

3.1 二進制數

二進制由 0 和 1 兩個數字組成,使用時必須以0b0B(不區分大小寫)開頭,例如:

//合法的二進制
int a = 0b101;  //換算成十進制爲 5
int b = -0b110010;  //換算成十進制爲 -50
int c = 0B100001;  //換算成十進制爲 33
//非法的二進制
int m = 101010;  //無前綴 0B,相當於十進制
int n = 0B410;  //4不是有效的二進制數字

讀者請注意,標準的C語言並不支持上面的二進制寫法,只是有些編譯器自己進行了擴展,才支持二進制數字。換句話說,並不是所有的編譯器都支持二進制數字,只有一部分編譯器支持,並且跟編譯器的版本有關係。

下面是實際測試的結果:

  • Visual C++ 6.0 不支持。
  • Visual Studio 2015 支持,但是 Visual Studio 2010 不支持;可以認爲,高版本的 Visual Studio 支持二進制數字,低版本的 Visual Studio 不支持。
  • GCC 4.8.2 支持,但是 GCC 3.4.5 不支持;可以認爲,高版本的 GCC 支持二進制數字,低版本的 GCC 不支持。
  • LLVM/Clang 支持(內嵌於 Mac OS 下的 Xcode 中)。

3.2 八進制數

八進制由 0~7 八個數字組成,使用時必須以0開頭(注意是數字 0,不是字母 o),例如:

/合法的八進制數
int a = 015;  //換算成十進制爲 13
int b = -0101;  //換算成十進制爲 -65
int c = 0177777;  //換算成十進制爲 65535

3.3 十六進制

十六進制由數字 0~9、字母 A~F 或 a~f(不區分大小寫)組成,使用時必須以0x0X(不區分大小寫)開頭,例如:

//合法的十六進制
int a = 0X2A;  //換算成十進制爲 42
int b = -0XA0;  //換算成十進制爲 -160
int c = 0xffff;  //換算成十進制爲 65535

3.4 這幾種進制的輸出格式

 

  short int long unsigned short unsigned int unsigned long
八進制 %ho %o %lo %ho %o %lo
十進制 %hd %d %ld %hu %u %lu
十六進制 %hx 或者 %hX %x 或者 %X %lx 或者 %lX %hx 或者 %hX %x 或者 %X %lx 或者 %lX

十六進制數字的表示用到了英文字母,有大小寫之分,要在格式控制符中體現出來:

  • %hx、%x 和 %lx 中的x小寫,表明以小寫字母的形式輸出十六進制數;
  • %hX、%X 和 %lX 中的X大寫,表明以大寫字母的形式輸出十六進制數。

八進制數字和十進制數字不區分大小寫,所以格式控制符都用小寫形式。

區分不同進制數字的一個簡單辦法就是,在輸出時帶上特定的前綴。在格式控制符中加上#即可輸出前綴,例如 %#x、%#o、%#lX、%#ho 等,請看下面的代碼:

#include <stdio.h>
int main()
{
    short a = 0b1010110;  //二進制數字
    int b = 02713;  //八進制數字
    long c = 0X1DAB83;  //十六進制數字
   
    printf("a=%#ho, b=%#o, c=%#lo\n", a, b, c);  //以八進制形似輸出
    printf("a=%hd, b=%d, c=%ld\n", a, b, c);  //以十進制形式輸出
    printf("a=%#hx, b=%#x, c=%#lx\n", a, b, c);  //以十六進制形式輸出(字母小寫)
    printf("a=%#hX, b=%#X, c=%#lX\n", a, b, c);  //以十六進制形式輸出(字母大寫)
   
    return 0;
}

運行結果:
a=0126, b=02713, c=07325603
a=86, b=1483, c=1944451
a=0x56, b=0x5cb, c=0x1dab83
a=0X56, b=0X5CB, c=0X1DAB83

  • 注意,整數和小數的有符號數在內存中都是以補碼形式存儲的,這樣方便加減運算。
  • 所以在將無符號數輸出爲有符號數的時候,需要考慮將無符號數看做是有符號數的補碼,並進行從補碼到原碼的變換。

四、小數的輸出

小數也可以使用 printf 函數輸出,包括十進制形式和指數形式,它們對應的格式控制符分別是:

  • %f 以十進制形式輸出 float 類型;
  • %lf 以十進制形式輸出 double 類型;
  • %e 以指數形式輸出 float 類型,輸出結果中的 e 小寫;
  • %E 以指數形式輸出 float 類型,輸出結果中的 E 大寫;
  • %le 以指數形式輸出 double 類型,輸出結果中的 e 小寫;
  • %lE 以指數形式輸出 double 類型,輸出結果中的 E 大寫。

下面的代碼演示了小數的表示以及輸出:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    float a = 0.302;
    float b = 128.101;
    double c = 123;
    float d = 112.64E3;
    double e = 0.7623e-2;
    float f = 1.23002398;
    printf("a=%e \nb=%f \nc=%lf \nd=%lE \ne=%lf \nf=%f\n", a, b, c, d, e, f);
   
    return 0;
}

 

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