什麼是類型提升
簡而言之,類型提升有點類似於不同數據類型的轉換,當兩個數據之間類型不同時,若直接進行比較或賦值運算時會自動先將兩個不同類型的數據均轉化為其中的某種類型再進行操作,因此發生了類型提升。導致一些意外性讓人茫然的錯誤。
類型提升的一些例子
例子1#include<stdio.h>
int main()
{
unsignedshort a = 6;
short b =-20;
int c = a + b;
unsignedshort d = a + b;
int e = d;
printf("%d, %d\n",sizeof(short),sizeof(int));
printf("%d, %d\n", c, e);
return 0;
}
輸出結果:
2, 4
-14, 65522
為什麼c和e的結果不一樣?
我想到的解釋是,int c = a + b;被編譯器解釋為:
=右邊需要的是int類型,編譯器直接把a和b轉換成了int類型,然後執行相加操作,再賦值
而不是像我原以為的按d,e方式解釋
問題:
1. 編譯器是否真按我上面的解釋進行?如果不是,那應該怎么解釋?
2. 如果編譯器是按我上面的解釋,其依據是什麼?為什麼不按d,e方式解釋?
下面是一些解釋,可供參考:
unsigned short 表示的範圍是 0 ~ 2^(16)-1 也就是2的十六次方減一
所以他是不可以表示負數的
所以-14被表示為 2^(16)- 14, 也就是65522
unsigned short a = 6;
short b = -20;
int c = a + b; // a由+運算轉為short與了運算, 得到-4(short) , 再由與=運算轉為int 得到 -4
unsigned short d = a + b; // a由+運算轉為short與了運算, 得到-4(short)。 再由與=運算轉為unsigned short 得到 -4的補碼 d 65522
int e = d; d 轉為 int
下面是我關於大整數加法的一個函式(寫的不是很好)
string BigAdd(string s1,string s2)
{
string c;
int carry=0;
for(int i=s1.size()-1;carry>0 || i>=0;i--)
{
if(i>s2.size()-1)
{
carry+=s1[i]-'0';
c.insert(c.begin(),carry%10+'0');
}
else if(i>=0)
{
carry+=s1[i]-'0';
carry+=s2[i]-'0';
c.insert(c.begin(),carry%10+'0');
}
else
c.insert(c.begin(),carry%10+'0');
carry/=10;
}
return c;
}
特別注意加粗的地方,當不斷循環進行i--到i=-1,我們主觀上會認為i=-1應該小於s2.size()-1可實際上卻是i>s2.size()-1;
實際上就是發生了類型轉換。解釋同“例子一”
正確的寫法應該是:
#include<iostream>
#include<string>
using namespace std;
string BigAdd(string s1,string s2)
{
string c;
int carry=0;
int len2=s2.size()-1;
for(int i=s1.size()-1;carry>0 || i>=0;i--)
{
if(i>len2)
{
carry+=s1[i]-'0';
c.insert(c.begin(),carry%10+'0');
}
else if(i>=0)
{
carry+=s1[i]-'0';
carry+=s2[i]-'0';
c.insert(c.begin(),carry%10+'0');
}
else
c.insert(c.begin(),carry%10+'0');
carry/=10;
}
return c;
}
int main()
{
string s1,s2;
while(cin>>s1>>s2)
{
if(s1>s2)
cout<<BigAdd(s1,s2)<<endl;
else
cout<<BigAdd(s2,s1)<<endl;
}
return 0;
}