【揭秘】C語言類型轉換時發生了什麼?

2020-12-26 電子工程專輯

在C語言中,數據類型指的是用於聲明不同類型的變量或函數的一個廣泛的系統,我們常用的算術類型包括兩種類型:整數類型和浮點類型。那麼相互之間具體是怎麼轉化的呢?

了解一類型轉換

不同數據類型的存儲大小和值範圍是不一樣的,程序在初始化的時候就已經設定了,例如:

int a = 9;
float b = 8.5;

a,b佔的字節大小不一樣,這個我們應該都知道,在C語言中一個表達式允許不同類型的數據進行運算,例如:

int a = 9;
float b = 8.5,c;
c = a + b;

因為計算機硬體在進行算術操作時,要求各操作數的類型具有相同的存儲位數以及一樣的存儲方式,所以就出現了類型轉換。

對於某些類型的轉換,編譯器可以隱式地自動進行,這種轉換稱為自動類型轉換

而有些類型轉換需要程式設計師顯式指明,那麼通常把這種轉換稱為強制類型轉換

自動類型轉換

自動轉換是在源類型和目標類型兼容以及目標類型廣於源類型時發生一個類型到另一類的轉換。我們先來看一段代碼

//vs2019
//來源:技術讓夢想更偉大
//作者:李肖遙
#include <stdio.h>
int main()
{
 //定義一個整型指針變量pPoint
 int* pPoint;

 //定義基本的數據的類型
 char c;
 short s;
 int i;
 long l;
 float f;
 double d;

 //將整型浮點型數據賦值給指針類型
 pPoint = c;
 pPoint = s;
 pPoint = i;
 pPoint = l;
 pPoint = f;
 pPoint = d;
 
 return 0;
}

由於指針變量和整型、浮點這些數據型的類型是不能相互賦值的,編譯報錯輸出:

那麼我們把同類型數據類型進行運算後賦值呢?

//vs2019
//來源:技術讓夢想更偉大
//作者:李肖遙
#include <stdio.h>
int main()
{
 //定義一個整型指針變量pPoint
 int* pPoint;

 //定義基本的數據的類型
 char c;
 short s;
 int i;
 long l;
 float f;
 double d;

 //將整型浮點型數據運算之後賦值給指針類型
 pPoint = c + c;
 pPoint = s + s;
 pPoint = i + i;
 pPoint = l + l;
 pPoint = f + f;
 pPoint = d + d;
 
 return 0;
}

  • double同類型運算,結果是一個double類型。

如下圖所示:


同類型運算中:

  • 整型:比int小的,都會轉換成int,比int大的不變。

那麼我們把不同類型數據類型進行運算後賦值呢?

//vs2019
//來源:技術讓夢想更偉大
//作者:李肖遙
#include <stdio.h>
int main()
{
 //定義一個整型指針變量pPoint
 int* pPoint;

 //定義基本的數據的類型
 char c;
 short s;
 int i;
 long l;
 float f;
 double d;

 //將整型浮點型數據混合運算賦值給指針類型
 pPoint = c + s;  // char + short = int
 pPoint = c + i;  // char + int = int
 pPoint = c + l;  // char + long = int
 pPoint = c + f;  // char + float = long
 pPoint = c + d;  // char + double = float
 
 return 0;
}

  • char類型與short類型運算,結果是一個int類型。
  • char類型與int類型運算,結果是一個int類型。
  • char類型與long類型運算,結果是一個long類型。
  • char類型與float類型運算,結果是一個float類型。
  • char類型與double類型運算,結果是一個double類型。

結果如下圖所示:


可以得出在不同類型運算中:

  • 如果兩邊均比int小或等於int,那麼結果為int。
  • 如果兩邊有比int大的,那麼結果為比int大的類型。

我們得到結論如圖:

int -> unsigned int -> long -> unsigned long -> long long -> unsigned long long

float -> double

自動轉換規則:

  • 圖中 橫向箭頭表示必須的轉換,如兩個float型數參加運算,雖然它們類型相同,但仍要先轉成double型再進行運算,結果亦為double型。
  • 圖中 縱向箭頭表示當運算符兩邊的運算數為不同類型時的轉換,如一個long 型數據與一個int型數據一起運算,需要先將int型數據轉換為long型, 然後兩者再進行運算,結果為long型。
  • 較高類型的數據轉換為較低類型時, 則可能有些數據丟失。
  • 較低類型的數據轉換為較高類型時,一般只是形式上有所改變, 而不影響數據的實質內容。
  • 所有這些轉換都是由系統自動進行的,使用時你只需從中了解結果的類型即可。

強制類型轉換

強制類型轉換是通過類型轉換運算來實現的。其一般形式為:

(類型說明符) (表達式) 

其作用就是把表達式的運算結果強制轉換成類型說明符所表示的類型的值。

//vs2019
//來源:技術讓夢想更偉大
//作者:李肖遙
#include<stdio.h>
#include<string.h>

int main()
{
    float f,x=1.3,y=1.4;
    int i = 4,a,b;
    a = x + y;
    b = (int)(x+y);
    f = 10/i;
    printf("a=%d,b=%d,f=%f,x=%f,y=%f\n",a,b,f,x,y);
}

運行結果如下:

我們從中可以看到,雖然x,y變強制轉換int型,但是最後輸出的值不變,強制類型轉換沒有影響x和y變量原本的類型。而上圖警告已經說明了一切。

注意:在C語言中,對一個變量賦值的時候,這個變量初始定義的類型包含了兩層含義:

  1. 編譯器把設定的數值放到這個內存空間,是數據類型的存儲方式解析後存進去的。

總結強調一點

進行強制類型轉換後,內存空間裡面的內容是不會發生改變的,改變的是運算時的臨時數據對象的類型,是你去讀取這個內存空間時的解析方法。所以,一定要對這個數據類型的內存空間和解析方式有一個清晰的認知。

相關焦點

  • C/C++編程筆記:C語言中的類型轉換,今天教你怎麼寫!
    所謂類型轉換基本上是從一種類型到另一種類型的轉換。類型轉換有兩種類型: 一、隱式類型轉換 通常在表達式中存在多個數據類型時發生。在這種情況下,將進行類型轉換(類型提升)以避免數據丟失。 變量的所有數據類型將升級為具有最大數據類型的變量的數據類型。
  • 詳解C語言數據類型:float與double
    這種論點提升到底是什麼?當較小尺寸的參數(特別是char,short和float)傳遞給可變參數函數(如printf之類的函數,其參數數量不固定)時,它們將轉換為較大尺寸。Char和short轉換為int,float轉換為double。為什麼這樣 據我所知,純粹出於歷史原因。
  • C語言數據類型思維導圖怎麼製作
    在使用C語言編寫程序時,數據類型是一個非常重要的內容,任何一個不被重視的數據錯誤都會使編譯器無法翻譯,導致程序報錯。使用思維導圖來梳理各個數據類型是一個很有效的記憶方法,接下來就為大家展示一下我用iMindMap製作的關於C語言基本數據類型的思維導圖。一、整型1.整型類型
  • C語言新增stdint.h頭文件的討論什麼是快類型什麼是小類型
    如果程式設計師希望寫出可移植的C語言程序,首先最重要的一點是不能假定位寬。C語言標準並沒有明確指定的 short、int、long 等類型的位寬,因此可能在某些平臺 sizeof(int) 等於 2,在其他平臺 sizeof(int) 等於 4,所以如果編寫的C語言代碼假定 sizeof(int) 是一個固定值,顯然就屬於不可移植的代碼。
  • C語言基礎(下)
    C語言的世界結構體類型什麼是結構體我們觀察現實世界的時候,可以發現很多的東西它都是由不同的部分組合起來的Student {char name[10];char * gender;char * mail;int age;} stu;方式三struct {char * name;char * gender;char * mail;int age;} stu;//之後無法再繼續定義變量結構體變量的初始化結構體定義時初始化
  • 學員問:C語言入門要掌握哪些基礎知識?
    01C語言程序的結構認識用一個簡單的c程序例子,介紹c語言的基本構成、格式、以及良好的書寫風格,使小夥伴對c語言有個初步認識。(注意:c語言中沒有直接表示二進位的整型常量,在c語言源程序中不會出現二進位。)
  • 華氏溫度換算公式及C語言轉換程序代碼
    它與攝氏溫度(C)和華氏溫度(F)之間的換算關係為F=9/5c+32, 或C=5/9(F-32)  華氏攝氏度與攝氏溫度之間的-C語言轉換程序  對於一個工程師或者說一個代碼狗來說,當然得知道,華氏攝氏度與攝氏溫度之間的C語言轉換程序啦。。。.
  • 「C語言從入門到入土」必備C語言基礎筆記整理
    一、C語言1、什麼是C語言?C語言是人寫機器看的一種語言。C語言是高級語言中的低級語言。C語言貼近硬體。C語言的入門學習比較簡單。彙編語言——>B語言——>C語言2、C語言的特性首先C語言就是你的女朋友。
  • 深入揭秘Spring類型轉換-框架設計的基石
    團隊內需要這樣的同學來為它保駕護航,驚爆之時方可泰然自諾。所以,你願意pick嗎?本系列將討論Spring Framework裡貫穿其上下文,具有舉足輕重地位的一個模塊:類型轉換(也可叫數據轉換)。正文Java是個多類型且強類型語言,類型轉換這個概念對它來說並不陌生。比如:自動類型轉換(隱式):小類型 -> 大類型。
  • 標準C+的類型轉換符:static_cast等
    、 const_cast 1 static_cast 用法:static_cast( exdivssion ) 該運算符把exdivssion轉換為type-id類型,但沒有運行時類型檢查來保證轉換的安全性。
  • C語言編程核心要點
    原文標題C語言編程核心要點,男人看了沉默,女人看了本文轉載自【微信公眾號:碼磚雜役,ID:whatis9527want】引言筆者有十餘年的C++開發經驗,相比而言,我的C經驗只有一兩年,C比較簡單,簡單到《The C Programming Language》(C程序設計語言)只有區區的200多頁,相比上千頁的C++大部頭,不得不說真的很人性化了
  • 想替代 C 的 Zig 語言成立了基金會
    Today, I am proud to announce the Zig Software Foundation, a 501(c)(3) not-for-profit corporation, dedicated to promoting, protecting, and advancing the Zig programming language
  • 2.5 JavaScript數據類型的轉換
    JavaScript是一種弱類型的程式語言,使用時無須指定數據類型。但在對表達式進行求值時,通常需要所有的操作數都屬於某種特定的數據類型。例如,進行算術運算時要求操作數都是數值類型,進行字符串連接運算時要求操作數都是字符串類型,而進行邏輯運算時則要求操作數都是布爾類型,這就需要數據類型之間的轉換。
  • C ++ 11 兩種改進得數據類型,空指針與強類型枚舉
    更多C++11內容,或者C++學習資料私信我 「代碼」即可獲取雖說C++現在17了,但是還是講下C++11中兩個類型吧,C ++從一開始就嘗試改進C的類型系統,添加類可以構建更好的類型和枚舉的類,這樣就不需要預處理器的某些用途(這在類型上並不安全)。C ++還為您執行更少的隱式類型轉換(例如不允許從void *進行隱式賦值),讓編譯器為您找到更多錯誤。
  • 入門C語言中的數組,字符串常量與指針
    數組 數組聲明為 數據類型 名稱[ constant-size ],並將一個數據類型的一個或多個實例分組到一個可尋址的位置,constant-size可能是一個表達式,但是該表達式必須求值為常量,例如: #define MAX_SIZE 16 ... int list [MAX_SIZE +
  • C語言怎麼樣?今天聊聊C語言的發展史!
    這個時候的丹尼斯.裡奇也沒閒著,在對B語言改良之後,就誕生了帶有類型的C語言(據裡奇自己說,有一段時間稱這種改良的語言為NB。即:new B。不過,在我們這些吃瓜群眾眼中看來也確實NB)。 4. unix時間線
  • C語言程序設計試題及答案
    A) int:a, b, c; B) int a; b; c;C) int a, b, c D) int a, b, c;20、C語言用( )表示邏輯「真」值。
  • 一文讀懂js中的隱式類型轉換
    前言今天來詳細了解一下javascript中的隱式類型轉換,通過在各種情況下發生的隱式類型的例子,來詳細的了解隱式類型轉換的過程。如何轉換-前置知識1.對象類型轉換當對象類型進行類型轉換時,會調用js內部一個方法toPrimitive, 此方法接收兩個參數,一個參數為需要轉換的對象,另一個方法接收一個期望類型,string或number。
  • 【愛找茬】都是C語言,單片機C語言和普通的C語言究竟有什麼差異呢?
    許多小夥伴在學完C語言後想入門單片機,但學著學著發現明明都是C語言,為什麼單片機C語言和我當初學的C語言有差異呢?今天小編就來梳理我們平時所學的C語言與單片機C語言的有什麼樣的不同。
  • C語言基礎知識
    pow(x, y)函數C 和 Python 語言的 pow(x, y) 方法都是用於返回 (x 的 y 次方) 的值,C 語言中其原型為:double pow(double x, double y)。數據類型整數類型下表列出了關於標準整數類型的存儲大小和值範圍的細節:浮點類型下表列出了關於標準浮點類型的存儲大小、值範圍和精度的細節:IO 函數