C語言整數

1、整數的概念

整數是咱們生活中經常使用的數據類型,也是編程中經常使用的一種數據,C語言使用int關鍵字來定義整數變量(int是 integer 的簡寫)。程序員

在定義變量的時候,能夠加signed、unsigned、short和long四種修飾符。編程

signed:有符號的,能夠表示正數和負數。數組

unsigned:無符號的,只能表示正數,例如數組的下標、人的身高等。ide

short:短的,如今主流的64位操做系統下,整數佔用內存4個字節,使用 4
個字節保存較小的整數綽綽有餘,會空閒出兩個字節來,這些字節就白白浪費掉了。在C語言被髮明的早期,或者在單片機和嵌入式系統中,內存都是很是稀缺的資源,全部的程序都在儘量節省內存。函數

long:長的,更長的整數。學習

2、整數的取值範圍

整數的取值範圍與計算機操做系統和C語言編譯器有關,沒有一個固定的數值,咱們能夠根據它佔用的內存大小來推斷它的取值範圍。測試

一個字節有8個位,表示的數據的取值範圍是2^8^-1,即255。操作系統

若是佔用的內存是兩個字節,無符號型取值範圍是2^8^ⅹ2^8^-1。.net

若是佔用的內存是四個字節,無符號型取值範圍是2^8^ⅹ2^8^ⅹ2^8^ⅹ2^8^-1。code

若是佔用的內存是八個字節,無符號型取值範圍是2^8^ⅹ2^8^ⅹ2^8^ⅹ2^8^ⅹ2^8^ⅹ2^8^ⅹ2^8^ⅹ2^8^-1。

若是是有符號,取值範圍減半,由於符號佔一個位。

下面用一個示例代碼來測試各類整數佔用內存的大小。

示例(book60.c)

/*
 * 程序名:book60.c,此程序演示整數佔用內存的大小和取值範圍。
 * 做者:C語言技術網(www.freecplus.net) 日期:20190525
*/
#include <stdio.h>

int main()
{
  short si;   // 短整數
  int   ii;   // 整數
  long  li;   // 長整數

  printf("sizeof short is %d\n",sizeof(short));
  printf("sizeof int is %d\n",sizeof(int));
  printf("sizeof long is %d\n",sizeof(long));
}

運行效果

在這裏插入圖片描述

sizeof是C語言中保留關鍵字,是一種運算符,不是函數,sizeof其實是獲取了數據在內存中所佔用的存儲空間,以字節爲單位。

int ii;       // sizeof(int)和sizeof(ii)均可以。

根據book60.c的測試結果,咱們能夠獲得各類整數的取值範圍。

類型簡寫 類型全稱 長度 取值範圍
short [signed] short [int] 2字節 -32768\~32767
unsigned short unsigned short [int] 2字節 0\~65535
int [signed] int 4字節 -2147483648\~2147483647
unsigned int unsigned [int] 4字節 0\~4294967295
long [signed] long [int] 8字節 -9223372036854775808\~ 9223372036854775807
unsigned long unsigned long [int] 8字節 0\~18446744073709551615

注意:

1)計算機用最高位1位來表達符號,unsigned修飾過的正整數不須要符號位,在表達正整數的時候比signed修飾的正整數取值大一倍。

2)在寫程序的時候,上表中括號[]的單詞能夠省略不書寫。

3)在寫程序的時候,給整數變量賦值不能超出變量的取值範圍,編譯的時候會出現相似如下的錯誤,程序運行也可能產生不可預後的後果。

在這裏插入圖片描述

4)如今計算機的內存不值錢,建議程序員少用short,慎用int,多用long,內存不是問題,程序的穩定高於一切。

3、整數的輸出

如下表格中,重點記住第1、二行十進制的輸出格式,二十年來,八進制數我歷來沒有用過,十六進制數只在顯示內存的地址時見過,因此你們沒必要關心八進制和十六進制的相關知識,瞭解便可。

在這裏插入圖片描述

注意一個坑:輸出格式控制符的類型最好與變量的類型一一對應,不然會出現意外的後果,示例:

int i=32767;
printf("i %hd,%d\n",i,i);
int j=32768;
printf("j %hd,%d\n",j,j);

輸出結果:

i 32767,32767
j -32768,32768     // 獲得了意外的輸出結果,32768超出了short的取值範圍。

%hd用於輸出短整數,最大值是32767,能夠輸出32767,但不能正常的輸出32768。

4、二進制數、八進制數和十六進制數的書寫

一個數字默認就是十進制的,表示一個十進制數字不須要任何特殊的格式。可是,表示一個二進制、八進制或者十六進制數字就不同了,爲了和十進制數字區分開來,必須採用某種特殊的寫法,具體來講,就是在數字前面加上特定的字符,也就是加前綴。

一、二進制

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

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

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

二、八進制

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

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

// 如下是非法的八進制
int m = 256;  // 無前綴 0,至關於十進制
int n = 03A2;  // A不是有效的八進制數字

三、十六進制

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

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

// 如下是非法的十六進制
int m = 5A;    // 沒有前綴 0X,是一個無效數字
int n = 0X3H;  // H不是有效的十六進制數字

四、須要注意的坑

在現實生活和工做中,咱們在寫十進制數的時候,爲了對齊或其它緣由,在數值前面加0是可有可無的,可是,在C語言中,不要在十進制數前加0,會被計算機誤認爲是八進制數。

5、經常使用的庫函數

C語言提供了幾個經常使用的庫函數,聲明以下:

int  atoi(const char *nptr);    // 把字符串nptr轉換爲int整數
long atol(const char *nptr);     // 把字符串nptr轉換爲long整數
int  abs(const int j);            // 求int整數的絕對值
long labs(const long int j);     // 求long整數的絕對值

示例(book61.c)

/*
 * 程序名:book61.c,此程序演示整數的atoi atol abs labs函數的使用
 * 做者:C語言技術網(www.freecplus.net) 日期:20190525
*/
#include <stdio.h>
#include <stdlib.h>   // 若是不包含這個頭文件,會出現意外的結果。

int main()
{
  int  ii;
  long ll;

  ii=atoi("-2147483647");
  ll=atol("-9223372036854775807");
  printf("ii=%d\n",ii);
  printf("ll=%ld\n",ll);

  ii=abs(ii);
  ll=labs(ll);
  printf("ii=%d\n",ii);
  printf("ll=%ld\n",ll);
}

運行效果

在這裏插入圖片描述

6、數據類型的別名

C語言容許程序員使用 typedef關鍵字來給數據類型定義一個別名,別名通常有兩個特色:1)名稱更短;2)更符合程序員的習慣。

例如unsigned int起個size_t的別名。

typedef unsigned int size_t;
size_t ii; 等同於 unsigned int ii;

咱們來看看strlen函數的幫助,strlen的返回值就是size_t類型。

在這裏插入圖片描述

7、隨機數

在實際開發中,會用到隨機數這個功能,例如編寫遊戲類的程序時就須要用到隨機數。

一、生成隨機數

在C語言中,咱們使用 \<stdlib.h\> 頭文件中的 srand和rand 函數來生成隨機數。

void srand(unsigned int seed);   // 隨機數生成器的初始化函數
int  rand();                        // 獲一個取隨機數

srand函數初始化隨機數發生器(俗稱種子),在實際開發中,咱們能夠用時間做爲參數,只要每次播種的時間不一樣,那麼生成的種子就不一樣,最終的隨機數也就不一樣,一般咱們採用\<time.h\> 頭文件中的 time 函數便可獲得一個精確到秒的時間做爲種子。

示例(book63.c)

/*
 * 程序名:book63.c,此程序用於演示隨機數
 * 做者:C語言技術網(www.freecplus.net) 日期:20190525
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main()
{
  int ii;

  srand(time(0));  // 播下隨機種子

  for (ii=0;ii<5;ii++)  // 生成5個隨機數
  {
    printf("%d ", rand());  // 獲取隨機數
  }

  printf("\n");
}

運行效果

在這裏插入圖片描述

二、生成必定範圍隨機數

在實際開發中,需求每每是必定範圍內的隨機數,對於產生必定範圍的隨機數,就須要使用必定的技巧,經常使用的方法是取模運算(取餘數),再加上一個加法運算:

int a = rand() % 50;   // 產生0~49的隨機數

若是要規定上下限:

int a = rand() % 51 + 100;   // 產生100~150的隨機數

取模即取餘數,rand()%51+100,rand()%51是產生 0\~50 的隨機數,後面+100保證 a最小隻能是 100,最大就是 50+100=150。

8、課後做業

1)編寫示例程序,判斷short、unsigned short、int、unsigned int、long、unsigned long佔用內存的字節數。

2)選擇題:請問int的取值範圍是多少?

(A)二十多億 (B) -2147483648\~2147483647 (C) 0\~4294967295

3)選擇題:請問long的取值範圍是多少?

(A)不少個億 (B) 足夠大 (C) -9223372036854775808\~9223372036854775807

4)編寫示例程序,從界面上輸入數字的字符串,存放在字符串變量中,而後用atoi函數轉換爲整數,加上100後再輸出到屏幕。

5)在C語言中,還有一種long long int的整數,各位寫一個程序,測試它佔用內存的字節數和取值範圍,並思考long long int類型是否具有實用價值。

6)編寫示例程序,測試short、unsigned short、int、unsigned、long、unsigned long賦值超出了取值範圍的後果。

7)重寫整數的abs和labs庫函數,實現其功能,函數的聲明以下:

int   ABS(const int j);                 // 求int整數的絕對值
long LABS(const long int j);           // 求long整數的絕對值

8)利用已經學習的知識,自定義一個函數,函數名是ctoi,把字符的'0'、'1'、'2'、'3'、'4'、'5'、'6'、'7'、'8'、'9'轉換爲整數的0、一、二、三、四、五、六、七、八、9。函數的聲明以下:

int ctoi(const char chr);
chr爲用字符方式表示的數字,函數的返回值爲數字的整數。

提示:採用if或switch語句,判斷chr的值,直接返回結果。

調用示例:

printf("'0' is %d\n",ctoi('0'));    // 輸出結果是'0' is 0
printf("'9' is %d\n",ctoi('9'));    // 輸出結果是'9' is 9

如下做業題難度較大,若是沒法完成,不要過於糾結,之後功力提高了再作。

9)自定義一個函數,函數名是POW,利用已經學習的知識,求一個數的n次冪,函數的聲明以下:

// 求x的y次冪,函數返回值爲x的y次冪。
long  POW(const int x,const int y);

調用示例:

printf("POW(2,3) is %lu\n",POW(2,3));      // 輸出結果是8
printf("POW(10,3) is %lu\n",POW(10,5));    // 輸出結果是100000

10)編寫示例程序,把字符串裏的數字所有加起來,例如字符串是"90576483975423",所有加起來結果是72。

11)重寫整數的atoi和atol庫函數,實現其功能,函數的聲明以下:

int   ATOI(const char *nptr);   // 把字符串nptr轉換爲int整數
long ATOL(const char *nptr);     // 把字符串nptr轉換爲long整數

提示:例如字符串的"12305",轉爲整數12305,拆開就是10000+2000+300+0+5,即1*104+2*103+3*102+0*101+5*100

12)生成五十二個隨機數,存放在數組中,範圍是1-52,不容許重複,最後在屏幕上顯示出來。

13)編寫一個撲克的發牌程序,一副牌除了大小王,還有52張牌,隨機洗牌,再發給四我的。

提示:

(1)把一副牌的所有牌面能夠用1-52的數值表示,數組是一個好選擇;

(2)洗牌就是生成範圍在1-52之間不重複的隨機數。

(3)定義四個數組,表明四我的,把洗好的52個數按順序賦給四個數組就好了。若是不想定義四個數組,用一個二維數組也行。

(4)把四個數組的值顯示出來,就是每一個人的牌面。

9、版權聲明

C語言技術網原創文章,轉載請說明文章的來源、做者和原文的連接。
來源:C語言技術網(www.freecplus.net)
做者:碼農有道

若是這篇文章對您有幫助,請點贊支持,或在您的博客中轉發個人文章,謝謝!!!若是文章有錯別字,或者內容有錯誤,或其餘的建議和意見,請您留言指正,很是感謝!!!

相關文章
相關標籤/搜索