C語言基礎知識-數據類型


            C語言基礎知識-數據類型

                                  作者:尹正傑

版權聲明:原創作品,謝絕轉載!否則將追究法律責任。

 

 

 

一.常量與變量

1>.關鍵字

    C的關鍵字共有32個。
1>.數據類型關鍵字(12個)     char,short,int,long,float,double,unsigned,signed,struct,union,enum,viod
2>.控制語句關鍵字(12個)
    if,else,switch,case,default,for,do,while,break,contiue,goto,return
3>.存儲類型關鍵字(5個)
    auto,extern,register,static,const
4>.其他關鍵字(3個)
    sizeof,typedef,volatile

2>.數據類型

    數據類型的作用:編譯器預算對象(變量)分配的內存空間大小。

1>.數據類型的定義
  變量的定義:
    數據類型 變量名[也叫標識符],如:"char Habby;"
  變量的賦值:
    變量名 = 值,如:“NAME=Jason Yin;”
    數據類型 變量名稱[標識符] = 值,如:"int AGE = 10;"

2>.標識符的命名規則
  字母,數字,下划線組成;
  不能以數字開頭(第一個字符必須為字母或下划線);
  見名知意;
  不能和同一函數內其他標識符重復;
  不能使用C語言內置的關鍵字;
  標識符中字母區分大小寫;

 

3>.常量

常量的作用:
    在程序運行過程中,其值不能被改變的量;
    常量一般出現在表達式或賦值語句中;

舉幾個例子:
    整型常量    : 100,200,-100,0 等
    實型常量    : 3.149.18,1.44 等
    字符型常量 : 'a','b','10','\n'
    字符串常量 : "age","123","jason"

常量的定義:
  const 數據類型 常量名;
  #deifne 常量名 值 

注意:
  通過“#deifne”定義的常量是根據值來匹配數據類型的,推薦使用這種方式定義常量。
  const修飾的常量是不安全的,可以通過指針來修改

4>.變量

變量的作用:
    在程序運行過程中,其值可以改變;
    變量在使用前必須先定義,定義變量前必須有相應的數據類型;

變量特點:
  變量在編譯時為其分配相應的內存空間;
  可以通過其名稱和地址訪問相應內存;  

5>.類型限定符

extenrn:
  聲明一個變量,extern聲明的變量沒有建立存儲空間。

const:
  定義一個常量,常量的值不能修改。例如 const int MONTH = 12volatile:
  防止編譯器優化代碼。

register:
  定義寄存器變量,提高效率。register是建議型的指令,而不是命令型的指令,如果CPU有空閑寄存器,那么register就生效,如果沒有空閑寄存器,那么register無效。

6>.使用案例

[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat variable_definitions.c 
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:y1053419035@qq.com
*/

#include <stdio.h>
#define PI 3.1415926

int main(void)
{
    //定義變量
    int _age = 18;
    printf("Age={%d}\n",_age);

    //定義常量
    const int MONTH = 12;
    printf("一年有{%d}個月\n",MONTH);

    //引用使用"#define"定義的變量
    printf("圓周率為:{%f}\n",PI);
}
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o variable_definitions variable_definitions.c 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./variable_definitions 
Age={18}
一年有{12}個月
圓周率為:{3.141593}
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 

 

二.進制

    進制也就是進制位,是人們規定的一種進位方法。對於任何一種進制-X進制,就表示某一位置的數運算時逢x進一位。十進制是逢十進一,十六進制是逢十六進一,二進制就是逢二進一,依次類推,x進制就是逢x進位。

1>.二進制

  二進制逢2進1,所有的數都是由0,1組成,如11+1=100
十進制轉二進制:
    除二反序取余法(將十進制數每次除以2,取出余數,按照結果倒敘排序)。
二進制專十進制:
    權值法(將二進制各個位數從0位開始乘以2的N次冪,將各個位數的結果相加)。

  當前計算機系統使用的基本上都是二進制系統,數據在計算機中主要以補碼的形式存儲。以下一些術語大家可以了解一下:
    bit(比特)
      一個二進制代表以為,一個位只能表示0或1兩種狀態。數據傳輸是習慣以“位”(bit)為單位。
    Byte(字節)
      一個字節為8個二進制,稱為8位,計算機中存儲的最小單位是字節。數據存儲是習慣以“字節”(Byte)為單位。
    WORD(雙字節)
      2個字節,即16位。
    DWORD
      兩個WORD,4個字節,即32位。
    1b
      1bit,1位。  
    1B
      1Byte,1字節,8位。
    1k,1K
      1024B。
    1M(1兆)
      1024k,1024*1024。
    1G
      1024M。
    1T
      1024G。
    1Kb(千位)
      1024bit,1024位。
    1Kb(千字節)
      1024Byte,1024字節。
    1Mb(兆位)
      1024Kb = 1024 * 1024bit。
    1MB(兆字節)
      1024KB=1024 * 1024Byte

2>.八進制

  八進制逢8進1,所有的數字是0到7組成。

  十進制轉八進制:
    除八反序取余法(將十進制數每次除以8,取出余數,按照結果倒敘排序)。
  
  二進制轉化為八進制:
    將二進制數字從右到左,每3個二進制數划分為一組,將每組數據的二進制轉換成八進制對應的數字即可。
  八進制轉換為二進制:     八四二一法則(將八進制的每一個位數上的數字拆開,分別用二進制表示即可。)

3>.十進制

  十進制逢10斤=1,有數字0-9組成,也是咱們生活中默認使用的進制。

  十進制轉換成二進制,八進制,十六進制的方法我這里就不啰嗦了,過於簡單我這里就不啰嗦了,我這里重點說一下十進制的小數轉換成二進制的方式。
  
  十進制小數轉換成二進制:
    小數部分和2相乘,取整數,不足1取0,每次相乘都是小數部分,順序看取整后的數就是轉化后的結果。為了方便說明,我們看一下十進制的0.521如何用二進制表示:
      0.521
    *    2
    ---------
      1.042   ---->第一次計算結果,取整數部分1,然后把小數部分0.042繼續和2相乘
      
       0.042   ---->這里的0.042就是上面計算的1.042的小數部分
    *     2
    ----------
       0.084   ----->第二次計算結果,取整數部分0,然后把小數部分0.084機型和2相乘

       0.084   ----->這里的0.084是上面計算的0.084的小數部分
    *     2
    ----------
       0.168   ------>第三次計算結果,取整數部分0,並終止計算,因為十進制0.521只有3位小數,顧我們只需要取3位二進制位即可,最終結果為0.100
      
    如上所述,我們來總結一下十進制轉換成二進制的幾個要點:
      (1)乘的時候只乘小數部分;
      (2)0.521只有3位,因此我們只需要算出3位二進制位置即可;
      (3)0.521的二進制數為:0.100

4>.十六進制 

  十六進制逢16進1,由數字0-9和字母A-F組成。
  
  十進制轉化為十六進制
    除十六反序取余法(將十進制數每次除以16,取出余數,按照結果倒敘排序,需要注意的是大於10的數字應該由A-F來表示)
  
  十六進制轉化為十進制
    權值法(將二進制各個位數從0位開始乘以16的N次冪,將各個位數的結果相加)。

  十六進制轉換為二進制
    八四二一法則(將十六進制的每一個位數上的數字拆開,分別用二進制表示即可。)

  二進制轉換為十六進制  
    將二進制數字從右到左,每4個二進制數划分為一組,將每組數據的二進制轉換成八進制對應的數字即可。

  十六進制轉換為八進制  
    思路就是先將十六進制轉換成二進制,再將二進制轉換成八進制。
  
  八進制轉換成十六進制
    思路就是先將八進制換轉成二進制,再將二進制轉換成十六進制。

5>.進制轉換表

 

 6>.在C程序中進制打印案例

[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat binary_conversion.c
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:y1053419035@qq.com
*/

#include <stdio.h>

int main(void)
{
    //十進制數字10
    int a = 10;
    printf("%d\n",a);

    //定義八進制
    int b = 010;
    printf("%d\n",b);

    //定義十六進制
    int c = 0x10;
    printf("%d\n",c);

    return 0;
}
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o binary_conversion binary_conversion.c
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./binary_conversion 
10
8
16
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat binary_conversion.c
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:y1053419035@qq.com
*/

#include <stdio.h>

int main(void)
{
    //十進制數字10
    int a = 10;
    printf("%o\n",a);

    //定義八進制
    int b = 010;
    printf("%o\n",b);

    //定義十六進制
    int c = 0x10;
    printf("%o\n",c);

    return 0;
}
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o binary_conversion binary_conversion.c
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./binary_conversion 
12
10
20
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat binary_conversion.c    #以八進制方式顯示
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat binary_conversion.c
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:y1053419035@qq.com
*/

#include <stdio.h>

int main(void)
{
    //十進制數字10
    int a = 10;
    printf("%x\n",a);

    //定義八進制
    int b = 010;
    printf("%x\n",b);

    //定義十六進制
    int c = 0x10;
    printf("%x\n",c);

    return 0;
}
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o binary_conversion binary_conversion.c
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./binary_conversion 
a
8
10
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat binary_conversion.c    #以十六進制方式顯示
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat binary_conversion.c
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:y1053419035@qq.com
*/

#include <stdio.h>

int main(void)
{
    //十進制數字10
    int a = 10;
    printf("%X\n",a);

    //定義八進制
    int b = 010;
    printf("%X\n",b);

    //定義十六進制
    int c = 0x10;
    printf("%X\n",c);

    return 0;
}
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o binary_conversion binary_conversion.c
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./binary_conversion 
A
8
10
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat binary_conversion.c    #以十六進制方式顯示

 

三.sizeof關鍵字

  sizeof不是函數,所以不需要包含任何頭文件,它的功能是計算一個數據類型的大小,單位為字節;
  
  sizeof的返回值為size_t;   sizeof_t類型在32位操作系統下是unsigned
int,是無符號的整數。
  
  注意:下面結果是根據64位操作系統獲取的數據類型大小,此時案例可參考下面的“使用sizeof查看各個數據類型占用內存大小案例”
    char(字符型,1Byte) < short(短整型,2Byte) < int(整型,4Byte)|float(單精度浮點型,4Byte)|long(長整型,4Byte) < long long(長長整型,8Byte)|double(雙精度浮點型,8Byte)
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat sizeof_demo.c
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:y1053419035@qq.com
*/

#include <stdio.h>

int main()
{
    int a;
    int b=sizeof(a);    //sizeof得到指定值占用內存大小,單位為字節.
    printf("b=%d\n",b);

    size_t c = sizeof(a);    //用無符號的方式輸出c的值
    printf("c=%u\n",c);

    return 0;
}
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o sizeof_demo sizeof_demo.c 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./sizeof_demo 
b=4
c=4
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
sizeof使用案例
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat sizeof_demo2.c
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:y1053419035@qq.com
*/

#include <stdio.h>

int main()
{
    int a = 10;
    //sizeof()求出數據類型在內存占用字節(Byte)大小
    int len1 = sizeof(a);
    printf("%d\n",a);
    printf("int = %d\n",len1);

    //單精度浮點型
    float b = 3.14;
    int len2 = sizeof(b);
    printf("%d\n",b);
    printf("float = %d\n",len2);
    
    //字符型
    char c = 'A';
    int len3 = sizeof(c);
    printf("%d\n",c);
    printf("char = %d\n",len3);

    //雙精度浮點型
    double d = 9.18;
    int len4 = sizeof(d);
    printf("%d\n",d);
    printf("double = %d\n",len4);

    //短整型
    short e = 10;
    int len5 = sizeof(e);
    printf("%d\n",e);
    printf("short = %d\n",len5);

    //長整型
    long f = 10;
    int len6 = sizeof(f);
    printf("%d\n",f);
    printf("long = %d\n",len6);

    //長長整型
    long long g = 10;
    int len7 = sizeof(g);
    printf("%d\n",g);
    printf("long long = %d\n",len7);
    
}
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o sizeof_demo2 sizeof_demo2.c
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./sizeof_demo2 
10
int = 4
2147483640
float = 4
65
char = 1
2147483639
double = 8
10
short = 2
10
long = 8
10
long long = 8
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
使用sizeof查看各個數據類型占用內存大小案例

 

四.計算機內存數值存儲方式

1>.原碼

一個數的原碼(原始的二進制碼)有如下特點:
    最高位作為符號位,0表示正,1表示負;
    其它數值部分都是數值本身絕對值的二進制數;
    負數的原碼是在其絕對值的基礎上,最高位變為1;

舉個例子,我們用一個字節的原碼來表示+15,-15,+0,-0
    +150000 1111
    -151000 1111
    +00000 0000
    -01000 0000

    原碼表示方法簡單易懂,帶有符號數本身轉換方便,只要符號位還原即可,但當兩個整數相減或不同符號相加時,必須比較兩個數哪個絕對值大,才能決定誰減誰,才能確定結果是正還是負,所以原碼不便於加減運算。

2>.反碼

一個數的反碼(原始的二進制碼)有如下特點:
   對於正數,反碼與原碼相同;
    對於負數,符號位不變,其它部位去反;
    
舉個例子,我們用一個字節的反碼來表示+15,-15,+0,-0
  +150000 1111
  -151111 0000
  +0 :  0000 0000
   -01111 1111

  反碼運算也不方便,通常用來作為求補碼的中間過渡

3>.補碼

在計算機中,數值一律用補碼來存儲。補碼特點如下:
  對於正數,原碼,反碼,補碼相同;
  對於負數,其補碼為它的反碼加1;
  補碼符號位不動,其他為求反,最后整個數加1,得到原碼;
舉個例子,我們用一個字節的補碼來表示
+15,-15,+0,-0
  +15 : 0000 1111
  -15 : 1111 0001
  +0 : 0000 0000
  -0 : 0000 0000

如果對補碼還迷糊的小伙伴,可參考博主推薦閱讀:https://www.cnblogs.com/yinzhengjie/p/8666354.html
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat complement.c
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:y1053419035@qq.com
*/

#include <stdio.h>

int main()
{
    int a = -15;
    printf("%x\n",a);

    return 0;
}
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o complement complement.c 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./complement 
fffffff1
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 

/*
  如上所述,輸出結果為“fffffff1”,改值用途二進制表示為:1111 1111 1111 1111 1111 1111 1111 0001

  符號位不變,其他去反,我們查看該二進制的反碼為:1000 0000 0000 0000 0000 0000 0000 1110

  我們在反碼的基礎上加1,得到最終的補碼為:1000 0000 0000 0000 0000 0000 0000 1111,即最高位是符號位,1代表負數,即改值二進制的補碼表示的為-15.
*/
補碼案例分析,使用C程序表示-15

4>.補碼的意義

在計算機系統中,數值一律使用補碼來存儲,主要原因如下:
  統一了0的編碼;
  將符號位和其他位統一處理;
  將減法運算轉變為加法運算;
  兩個用補碼表示的數相加時,如果最高位(符號位)有進位,則進位被舍棄。

 

五.整型(int)

1>.整型變量的定義和輸出

%d
  輸出一個有符號的10進制int類型

%o(字母o)
  輸出8進制的int類型

%x
  輸出16進制的int類型,字母以小寫輸出

%X
  輸出16進制的int類型,字母以大寫輸出

%u
  輸出一個10進制的無符號數
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat int_dome1.c 
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:y1053419035@qq.com
*/

#include <stdio.h>

int main()
{
    int a = 123;        //定義變量a,以10進制方式賦值為123.
    int b = 0567;        //定義變量b,以8進制方式賦值0567.
    int c = 0xabc;        //定義變量c,以16進制方式賦值為0xabc.
    
    printf("a = %d\n",a);
    printf("8進制:b=%o\n",b);
    printf("10進制:b=%d\n",b);
    printf("16進制:c=%x\n",c);
    printf("16進制:c=%X\n",c);
    printf("16進制:c=%d\n",c);

    unsigned int d = 0xffffffff;    //定義無符號int變量d,以16進制方式賦值
    printf("有符號方式打印:d = %d\n",d);
    printf("無符號方式打印:d = %u\n",d);
    return 0;
}
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o int_dome1 int_dome1.c 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./int_dome1 
a = 123
8進制:b=567
10進制:b=375
16進制:c=abc
16進制:c=ABC
16進制:c=2748
有符號方式打印:d = -1
無符號方式打印:d = 4294967295
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat int_dome1.c      #使勁戳我可參考實際案例

2>.整型變量的輸入

[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat int_dome2.c 
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:y1053419035@qq.com
*/

#include <stdio.h>

int main()
{
    int num;
    printf("請輸入a的值:>>> ");

    //不要加換行符"\n"
    scanf("%d",&num);

    //打印輸入的int類型的值
    printf("num = %d\n",num);

    return 0;
}
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o int_dome2 int_dome2.c 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./int_dome2 
請輸入a的值:>>> 20190520
num = 20190520
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 

3>.short,int,long,long long

short(短整型)
  2字節

int(整型)
  4字節

long(長整型)
  windows為4字節,Linux為4自己(32位),8字節(64位)

long long(長長整型)
  8字節

溫馨提示:
  整型數據在內存中占用的字節數與所選擇的操作系統有關。雖然C語言標准中沒有明確規定整型數據的長度,但long類型整型的長度不能短於int類型,short類型整數的長度長於int類型。
  當一個小的數據類型賦值給一個大的數據類型,不會出錯,因為編譯器會自動轉化。但是當一個大的類型賦值給一個小的數據類型,那么就可能丟失高位。

以下是整型常量及其所需類型
10
  代表int類型
10l,10L
  代表long類型
10ll,10LL
  代表long long類型
10u,10U
  代表unsigned int類型
10ul,10UL
  代表unsigned long類型
10ull,10ULL
  代表unsigned long long類型


接下來我們查看一下打印格式及其含義
%d
  輸出int類型
%l  
  輸出long類型
%ll
  輸出long long類型
%hu
  輸出unsigned short類型
%u
  輸出unsigned int類型
%lu
  輸出unsigned long類型
%llu
  輸出unsigned long long類型
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat int_dome3.c
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:y1053419035@qq.com
*/

#include <stdio.h>

int main()
{
    short a = 10;
    int b = 10;
    long c = 10L;
    long long d = 10LL;

    printf("sizeof(a) = %u\n",sizeof(a));
    printf("sizeof(b) = %u\n",sizeof(b));
    printf("sizeof(c) = %u\n",sizeof(c));
    printf("sizeof(d) = %u\n",sizeof(d));

    printf("short a = %hd\n",a);
    printf("int b = %d\n",b);
    printf("long c = %ld\n",c);
    printf("long long d = %lld\n",d);

    unsigned short a2 =20u;
    unsigned int b2 = 20u;
    unsigned long c2 = 20ul;
    unsigned long long d2 = 20ull;
    
    printf("unsigned short a = %hu\n",a2);
    printf("unsigned int b = %u\n",b2);
    printf("unsigned long c = %lu\n",c2);
    printf("unsigned long long d = %llu\n",d2);

    return 0;
}
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o int_dome3 int_dome3.c 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./int_dome3
sizeof(a) = 2
sizeof(b) = 4
sizeof(c) = 8
sizeof(d) = 8
short a = 10
int b = 10
long c = 10
long long d = 10
unsigned short a = 20
unsigned int b = 20
unsigned long c = 20
unsigned long long d = 20
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat int_dome3.c        #使用案例

4>.有符號和無符號的區別

一個有符號的整型數據可以分為兩部分:一部分是符號位,一部分是數字位。

無符號數據類型只包含數字位部分。

當我們寫程序要處理一個不可能出現負數的時候,一般用無符號數,這樣可以增大數的表達最大值。


有符號和無符號整型取值范圍如下:
short   占用2字節,取值范圍在-32768到32767(-2的15次方到2的15次方減1)。 int   占用4字節,取值范圍在-2147483648代2147483647(-2的31次方到2的31次方減1) long   占用4字節,取值范圍在-2147483648代2147483647(-2的31次方到2的31次方減1) unsigned short   占用2自己,取值范圍在0到65535(0到2的15次方減1) unsigned int   占用4字節,取值范圍在0到4294967295(0到2的32次方減1) unsigned long   占用4字節,取值范圍在0到4294967295(0到2的32次方減1)

 

六.字符型(char)

1>.字符變量的定義和輸出

    字符型變量用於存儲一個單一字符,在C語言中用char表示,其中每個字符變量都會占用1個字節。在給字符型變量賦值時,需要用一對英文半角格式的單引號(' ')把字符括起來。

    字符變量實際上並不是把該字符本身放到變量的內存單元中去,而是將該字符對應的ASCII編碼放到變量中的存儲單元中。char的本質就是一個1字節大小的整型。
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat char_demo.c 
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:y1053419035@qq.com
*/

#include <stdio.h>

int main(void)
{
    char ch = 'a';

    printf("sizeof(ch) = %u\n",sizeof(ch));
    
    printf("ch(%%c) = %c\n",ch);        //輸出字符串
    
    putchar(ch);                //該方法只能輸出字符,該行及下面一行均是輸出字符
    
    putchar('\n');
    
    printf("ch(%%d) = %d\n",ch);        //打印'a'對應的ASSCII的值

    return 0;
}
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o char_demo char_demo.c 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./char_demo
sizeof(ch) = 1
ch(%c) = a
a
ch(%d) = 97
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat char_demo.c

2>.字符變量的輸入

[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat char_demo2.c 
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:y1053419035@qq.com
*/

#include <stdio.h>

int main(void)
{
    char input;
    
    //scanf("%c",&input);        //接收用戶輸入的一個字符
    
    input = getchar();        //除了使用上面的scanf方法獲取用戶輸入,我們還可以用getchar來獲取用戶輸入的字符

    putchar(input);            //將用戶輸入的字符打印出來
    
    putchar('\n');            //上面打印出來並沒有換行,我們可以人為的給它加一個換行符
    
    return 0;        
}
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o char_demo2 char_demo2.c 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./char_demo2
Y
Y
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat char_demo2.c

3>.ASCII對照表

ASCII碼大致有以下兩部組成:
  ASCII非打印控制字符:
    ASCII表上的數字0-31分配了控制字符,用於控制像打印機等一些外圍設備。    

  ASCII打印字符
    數字32-126分配了能在鍵盤上找到的字符,當查看或打印文檔時就會出現。數字127代表Del命令。
ASCII值 控制字符 ASCII值 控制字符 ASCII值 控制字符 ASCII值 控制字符
0 NUT 32 (space) 64 @ 96
1 SOH 33 ! 65 A 97 a
2 STX 34 " 66 B 98 b
3 ETX 35 # 67 C 99 c
4 EOT 36 $ 68 D 100 d
5 ENQ 37 % 69 E 101 e
6 ACK 38 & 70 F 102 f
7 BEL 39 , 71 G 103 g
8 BS 40 ( 72 H 104 h
9 HT 41 ) 73 I 105 i
10 LF 42 * 74 J 106 j
11 VT 43 + 75 K 107 k
12 FF 44 , 76 L 108 l
13 CR 45 - 77 M 109 m
14 SO 46 . 78 N 110 n
15 SI 47 / 79 O 111 o
16 DLE 48 0 80 P 112 p
17 DCI 49 1 81 Q 113 q
18 DC2 50 2 82 R 114 r
19 DC3 51 3 83 S 115 s
20 DC4 52 4 84 T 116 t
21 NAK 53 5 85 U 117 u
22 SYN 54 6 86 V 118 v
23 TB 55 7 87 W 119 w
24 CAN 56 8 88 X 120 x
25 EM 57 9 89 Y 121 y
26 SUB 58 : 90 Z 122 z
27 ESC 59 ; 91 [ 123 {
28 FS 60 < 92 / 124 |
29 GS 61 = 93 ] 125 }
30 RS 62 > 94 ^ 126 `
31 US 63 ? 95 _ 127 DEL
特殊字符解釋
NUL空 VT 垂直制表 SYN 空轉同步
STX 正文開始 CR 回車 CAN 作廢
ETX 正文結束 SO 移位輸出 EM 紙盡
EOY 傳輸結束 SI 移位輸入 SUB 換置
ENQ 詢問字符 DLE 空格 ESC 換碼
ACK 承認 DC1 設備控制1 FS 文字分隔符
BEL 報警 DC2 設備控制2 GS 組分隔符
BS 退一格 DC3 設備控制3 RS 記錄分隔符
HT 橫向列表 DC4 設備控制4 US 單元分隔符
LF 換行 NAK 否定 DEL 刪除

4>.轉義字符

    所有的轉義字符和所對應的意義:
轉義字符
意義
ASCII碼值(十進制)
\a
響鈴(BEL)
007
\b
退格(BS) ,將當前位置移到前一列
008
\f
換頁(FF),將當前位置移到下頁開頭
012
\n
換行(LF) ,將當前位置移到下一行開頭
010
\r
回車(CR) ,將當前位置移到本行開頭
013
\t
水平制表(HT) (跳到下一個TAB位置)
009
\v
垂直制表(VT)
011
\\
代表一個反斜線字符''\'
092
\'
代表一個單引號(撇號)字符
039
\"
代表一個雙引號字符
034
\? 代表一個問號 063
\0
空字符(NUL)
000
\ddd
1到3位八進制數所代表的任意字符
三位八進制
\xhh
1到2位十六進制所代表的任意字符
十六進制

 5>.數值溢出 

當超過了一個數據類型能夠存放最大的范圍時,數值會溢出。

有符號最高位溢出的區別:符號位溢出會導致數的正負發生改變,但最高位的溢出會導致最高位丟失。

char   占用1字節    取值范圍在-128到127(負的2的7次方到2的7次方減1)

unsigned char    占用1字節    取值范圍0到255(0到2的8次方-1
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat char_demo3.c 
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:y1053419035@qq.com
*/

#include <stdio.h>

int main(void)
{
    char input;
    
    //符號位溢出會導致數的正負發生改變,0x7f(十六進制表示法)對應的二進制為:0111 1111,給其加2后為:1000 0001,這是負數的原碼,其補碼為:1111 1111,十進制為-127.
    input = 0x7f + 2;    //127 + 2
    printf("%d\n",input);    

    //最高位的溢出會導致高位丟失,0xff(十六進制表示法)對應的二進制為:1111 1111,給其加1后變為:1 0000 0000,char只有8位最高位的溢出(有網友也喜歡說是高位截短),糾其原因是一個字節存取8個比特位,因此結果為:0000 0000,十進制為0.
    unsigned char input2;
    input2 = 0xff +1;     //255+1
    printf("%u\n",input2);

    //和上面案例原理相同,0xff(十六進制表示法)對應的二進制為:1111 1111,給其加2后變為:1 0000 0001,高位截斷后結果為:0000 0001,十進制為1.
    input2 = 0xff + 2;
    printf("%u\n",input2);

    return 0;        
}
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o char_demo3 char_demo3.c 
char_demo3.c: In function ‘main’:
char_demo3.c:19:2: warning: large integer implicitly truncated to unsigned type [-Woverflow]        #我們在編譯成可執行文件時,發現有warning的提示信息,說是無符號類型數據溢出(-Woverflow)啦,此消息咱們忽略即可,因為這個溢出是咱們人為造成溢出的~
  input2 = 0xff +1;  //255+1
  ^
char_demo3.c:23:2: warning: large integer implicitly truncated to unsigned type [-Woverflow]
  input2 = 0xff + 2;
  ^
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./char_demo3
-127
0
1
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 

 

七.實型(浮點型)

實型變量也可以成為浮點型變量,浮點型變量是用來存儲小數數值的。在C語言中,浮點型變量分為兩種:單精度浮點數(float),雙精度浮點數(double),但是double型變量所表示的浮點數比float型變量更精確。

  float:占用4字節,7位有效數字。

  double:占用8字節,15~16位有效數字。

由於浮點型變量是由有限的存儲單元組成的,因此只能提供有限的有效數字。在有效位以外的數字將被舍去,這樣可能會產生一些誤差。
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat float_demo.c 
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:y1053419035@qq.com
*/

#include <stdio.h>

int main(void)
{
    float a = 3.14f;        //或者3.14F,這是傳統賦值
    
    double b = 3.14;        

    printf("a = %f\n",a);
    printf("b = %f\n",b);

    a = 3.2e3f;                //或者3.2E3f,科學法賦值,表示3.2 * 1000 = 3200
    printf("a1 = %f\n",a);
    
    a = 100e-3f;                //表達式為:100 * 0.001 = 0.1
    printf("a2 = %f\n",a);
    
    a = 3.1415926f;
    printf("a3 = %f\n",a);        //結果為3.141593,因為我們知道a是float類型,占用4字節,僅僅有7位有效數字,最后一位會進行四舍五入法得結果

    float r = 2;

    float s = r * r * 3.14;

    printf("%.2f\n",s);          //注意,“%.2f"表示保留小數點后2位.

    return 0;
}
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o float_demo float_demo.c 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./float_demo 
a = 3.140000
b = 3.140000
a1 = 3200.000000
a2 = 0.100000
a3 = 3.141593
12.56
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 

 

.字符串格式化輸入和輸出

1>.字符串常量

字符串是內存中一段連續的char空間,以'\0'(數字0)結尾。
字符串常量是由雙引號括起來的字符序列,如"chaina","C parogram","$PATH"等都是合法的字符串常量。

字符串常量與字符常量的不同:

每個字符串的結尾,編譯器會自動的添加一個結束標志位“\0”,即"a"包含兩個字符'a''\0'

2>.printf函數和putchar函數

printf是輸出一個字符串,putchar輸出一個char。

printf格式字符:
打印格式      對應數據類型            含義
%d          int            接收整數值並將它表示為有符號的十進制整數
%hd         short int           端整數
%hu        unsigned short       無符號短整數
%o         unsigned int        無符號8進制整數
%u         unsigned int        無符號10進制整數
%x,%X       unsigned int        無符號16進制整數,x對應的是abcdef,X對應的是ABCDEF
%f          float           單精度浮點數
%lf         double           雙精度浮點型
%e,%E        double           科學計數法表示的數,此處"e"的大小寫代表輸出時用"e"的大小寫
%c          char            字符型,可以把輸入的數字按照ASCII對應轉換為對應的字符
%s          char *           字符串,輸出字符串中的字符直至字符串的空字符(字符串以'\0'結尾,這個'\0'即空字符)
%p          void            以16進制形式輸出指針
%%          %              輸出一個百分號,即"%"


printf附加格式:
字符                含義
l(這個是小寫字母l)        附加在d,u,x,o前面,表示長整數
-                 左對齊
m(代表一個整數)         數據最小寬度
0(這個是數字0)         將輸出的前面補上0知道滿指定列環位置不可用搭配使用-
m.n(代表一個整數)        m值域寬,即對應的輸出項在輸出設備上所占的字符數,n指進度,用戶說明輸出的實型數的小數位數。對數值型的來說,未指定n時,隱含的精度為n=6位。
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat echo.c 
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:y1053419035@qq.com
*/

#include <stdio.h>

int main()
{
    int a = 100;
    printf("a = %d\n",a);    //格式化輸出一個字符串
    printf("%p\n",&a);    //輸出變量a在內存中的地址編碼
    printf("%%d\n");

    char c = 'a';
    putchar(c);        //putchar只有一個參數,就是要輸出的char
    
    long long a3 = 1000;
    printf("%lld,%llx,%llo\n",a3,a3,a3);

    int abc = 10;
    printf("abc = '%6d'\n",abc);
    printf("abc = '%-6d'\n",abc);
    printf("abc = '%0d'\n",abc);
    printf("abc = '%-06d'\n",abc);

    double d = 12.3;
    printf("d = \'%-10.3lf'\n",d);
    return 0;
}
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o echo echo.c 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./echo 
a = 100
0x7fff18387bec
%d
a1000,3e8,1750
abc = '    10'
abc = '10    '
abc = '10'
abc = '10    '
d = '12.300    '
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat echo.c      #printf和putchar使用案例

3>.scanf函數與getchar函數

getchar是從標准輸入設備讀取一個char
scanf通過%轉義的方式可以得到用戶通過標准輸入設備輸入的數據
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat echo2.c 
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:y1053419035@qq.com
*/

#include <stdio.h>

int main()
{
    char ch1;
    char ch2;
    char ch3;
    int a;
    int b;

    printf("請輸入ch1的字符:>>> ");
    ch1 = getchar();
    printf("ch1 = %c\n",ch1);

    getchar();                //測試此處getchar()的作用
    
    printf("請輸入ch2的字符:>>> ");
    ch2 = getchar();
    printf("\'ch2 = %ctest\'\n",ch2);

    getchar();                //測試此處getchar()的作用
    printf("請輸入ch3的字符:>>> ");
    scanf("%c",&ch3);            //這里第二個參數一定是變量的地址,而不是變量名
    printf("ch3 = %c\n",ch3);    

    printf("請輸入a的值:>>> ");
    scanf("%d",&a);
    printf("a = %d\n",a);

    printf("請輸入b的值:>>> ");
    scanf("%d",&b);
    printf("b = %d\n",b);

    return 0;
}
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# gcc -o echo2 echo2.c 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# ./echo2 
請輸入ch1的字符:>>> a
ch1 = a
請輸入ch2的字符:>>> b
'ch2 = btest'
請輸入ch3的字符:>>> c
ch3 = c
請輸入a的值:>>> 100
a = 100
請輸入b的值:>>> 200
b = 200
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# 
[root@node101.yinzhengjie.org.cn /yinzhengjie/code/day002]# cat echo2.c      #printf和getchar使用案例

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM