⑴ java中的強制類型轉換
在Java中強制類型轉換分為基本數據類型和引用數據類型兩種,這里我們討論的後者,也就是引用數據類型的強制類型轉換。
在Java中由於繼承和向上轉型,子類可以非常自然地轉換成父類,但是父類轉換成子類則需要強制轉換。因為子類擁有比父類更多的屬性、更強的功能,所以父類轉換為子類需要強制。那麼,是不是只要是父類轉換為子類就會成功呢?其實不然,他們之間的強制類型轉換是有條件的。
當我們用一個類型的構造器構造出一個對象時,這個對象的類型就已經確定的,也就說它的本質是不會再發生變化了。在Java中我們可以通過繼承、向上轉型的關系使用父類類型來引用它,這個時候我們是使用功能較弱的類型引用功能較強的對象,這是可行的。但是將功能較弱的類型強制轉功能較強的對象時,就不一定可以行了。
舉個例子來說明。比如系統中存在Father、Son兩個對象。首先我們先構造一個Son對象,然後用一個Father類型變數引用它:
Father father = new Son();
在這里Son 對象實例被向上轉型為father了,但是請注意這個Son對象實例在內存中的本質還是Son類型的,只不過它的能力臨時被消弱了而已,如果我們想變強怎麼辦?將其對象類型還原!
Son son = (Son)father;
這條語句是可行的,其實father引用仍然是Father類型的,只不過是將它的能力加強了,將其加強後轉交給son引用了,Son對象實例在son的變數的引用下,恢復真身,可以使用全部功能了。
前面提到父類強制轉換成子類並不是總是成功,那麼在什麼情況下它會失效呢?當引用類型的真實身份是父類本身的類型時,強制類型轉換就會產生錯誤。例如:
Father father = new Father();
Son son = (Son) father;
這個系統會拋出ClassCastException異常信息。
所以編譯器在編譯時只會檢查類型之間是否存在繼承關系,有則通過;而在運行時就會檢查它的真實類型,是則通過,否則拋出ClassCastException異常。
所以在繼承中,子類可以自動轉型為父類,但是父類強制轉換為子類時只有當引用類型真正的身份為子類時才會強制轉換成功,否則失敗。
public class TestCastClassException
{
public static void main(String[] args)
{
Father father = new Son();
//這兩句話是不對的,因為一個father類型的引用(指針)是看不見、看不到son中新定義的數據成員或者成員函數的
//雖然這個對象的本質是Son類型的,它也確實有這樣的數據成員和成員函數,但是指針的作用范圍不夠,它看不到。
//代碼後面附上模型分析
//father.son = 2;
//father.show_son();
father.show_father();
father.show();
Father father1 = (Father)father;//一個對象在內存中被new出來後,只能選擇訪問它的方式,不能修改它的布局(包含的成員的個數等)
father1.show();
} //main
}
class Father
{
public int father = 2;
Father(){}
void show()
{
System.out.println("This is father");
}
void show_father()
{
System.out.println("father!!");
}
}
class Son extends Father
{
public int son = 1;
Son(){}
void show()
{
System.out.println("This is son");
}
void show_son()
{
System.out.println("son!!");
}
}
⑵ Java中的強制類型轉換是如何轉換的
java中數據類型的強制轉換是通過強制轉換語句完成的,強制轉換語句的格式為「目標數據類型 變數 = (目標數據類型) 數據;」。下面給出例子:
1、定義兩個位元組數據類型a、b、c,分別賦予1和2和a+b的值,進行加法運算的式子a+b=3,得出的結果「3」將會被編譯環境判定為整形數據,把這個整形數據賦值給c,系統將會報錯,這樣就需要用到格式為「目標數據類型 變數 = (目標數據類型) 數據;」的強制轉換語句。
2、根據強制轉換語句的格式,易得「byte c = (byte)(a+b);」;
3、這樣就把整形數據的「3」賦值給位元組數據類型的c了,其中完成數據的強制類型轉換。
(2)編譯器數據類型轉換規則擴展閱讀:
基本類型 轉換原則:
1、類型轉換主要在在賦值、方法調用、算術運算三種情況下發生。
a、賦值和方法調用 轉換規則:從低位類型到高位類型自動轉換;從高位類型到低位類型需要強制類型轉換:
(1)布爾型和其它基本數據類型之間不能相互轉換;
(2)byte型可以轉換為short、int、、long、float和double;
(3)short可轉換為int、long、float和double;
(4)char可轉換為int、long、float和double;
(5)int可轉換為long、float和double;
(6)long可轉換為float和double;
(7)float可轉換為double;
b、算術運算 中的類型轉換:
1、基本就是先轉換為高位數據類型,再參加運算,結果也是最高位的數據類型;
2、byte short char運算會轉換為Int;
(1)如操作數之一為double,則另一個操作數先被轉化為double,再參與算術運算。
(2)如兩操作數均不為double,當操作數之一為float,則另一操作數先被轉換為float,再參與運算。
(3)如兩操作數均不為double或float,當操作數之一為long,、則另一操作數先被轉換為long,再參與算術運算。
(4)如兩操作數均不為double、float或long,則兩操作數先被轉換為int,再參與運算。
特殊:
(1)如採用+=、*=等縮略形式的運算符,系統會自動強制將運算結果轉換為目標變數的類型。
(2) 當運算符為自動遞增運算符(++)或自動遞減運算符(--)時,如果操作數為byte,short或char類型不發生改變;
⑶ C語言中為什麼3+3.14表達式結果類型為double
應該是double類型吧
在不同類型的混合運算中,編譯器也會自動地轉換數據類型,將參與運算的所有數據先轉換為同一種類型,然後再進行計算。轉換的規則如下:
轉換按數據長度增加的方向進行,以保證數值不失真,或者精度不降低。例如,int 和 long 參與運算時,先把 int 類型的數據轉成 long 類型後再進行運算。
所有的浮點運算都是以雙精度進行的,即使運算中只有float 類型,也要先轉換為 double 類型,才能進行運算。
char 和 short 參與運算時,必須先轉換成 int 類型。
⑷ 大一C++問題 double類型的變數是否可以賦給整形變數字元型呢數據類型轉換的基本原則是什麼
樓主你好
數據類型的轉換規則為:
(1)從類型高(強調精度高)的轉換到類型低(強調精度低)的 這樣一般都會得到編譯器的警告
因為精度高的變為精度低的數據 會失去數據原本的精度 這樣容易丟失數據
例如double a=5.5
int b=a
這里b=5 失去了小數一位.5的精度
數據不精確 但是可以轉換
(2)從類型低的轉換到類型高的 會正常轉換 沒有警告
至於字元類型 是完全可以賦值給整型變數的
如果樓主知道 ASCII碼
那麼字元賦值給整型變數 就是講字元對應的ASCII碼(整型的)賦值給整型變數
(介於樓主是大一 可能才接觸c++ 就只講這么多了哈^_^)
希望能幫助你哈
⑸ C語言強制類型轉換
強制類型轉換是把變數從一種類型轉換為另一種數據類型。
例如,如果您想存儲一個 long 類型的值到一個簡單的整型中,您需要把 long 類型強制轉換為 int 類型。您可以使用強制類型轉換運算符來把值顯式地從一種類型轉換為另一種類型。
(5)編譯器數據類型轉換規則擴展閱讀:
舉例說明
使用強制類型轉換運算符把一個整數變數除以另一個整數變數,得到一個浮點數:
#include <stdio.h>int main()
{
int sum = 17, count = 5;
double mean;
mean = (double) sum / count;
printf("Value of mean : %f
", mean );
}
當上面的代碼被編譯和執行時,它會產生下列結果:
Value of mean : 3.400000
⑹ C語言 共用體中的各種類型轉換的原則
一、基礎知識和數據類型、表達式
1、{},[],(),『』,「」不配對。解決這個問題最好的方法就是每當寫這些符號的時候就先寫成一對,然後再在中間加內容。
2、忘記在語句的末尾加分號,或在預處理命令後多加分號。記住:每一個語句的後邊都要加分號,而預處理命令並不是語句,所以不加分號,他們必須每行一條,不能把多個命令寫在一行。
3、混淆/和\;注釋對應的符號是/* */,而轉義字元是以\開頭,除號是/。
4、printf()和scanf()的參數設置有誤,主要表現在以下幾方面:
l 類型不匹配的問題。(例如:有float a=3.5,但輸出的時候printf(「a=%d」,a);則屏幕上會顯示出a=0.00000或者提示其它運行錯誤)。基本原則是:float對應%f, int對應%d, char對應%c。
l 個數不匹配。無論是哪個函數,都可以有n個參數,第一個永遠是「」括起來的內容,表示輸出格式。剩下的n-1個是輸出的變數或者輸入的變數的地址。需要注意的是,如果後邊有n-1個參數,那麼前邊一定對應n-1個%f一類的格式說明符。
l scanf()中變數前忘了加&。記住:scanf()中變數前要有&(但後邊學到的字元數組名和指針前不用加)
5、定義標識符的時候經常出現使用非法字元的情況,例如:標識符中不能用空格,也就是說不能有這樣的定義:int radium of circle;一般情況下可用下劃線將三個單詞連接在一起。
6、在使用變數前未定義,或未初始化。例如:若下邊的sum未定義,則在編譯時會提示相應的錯誤信息,而若未初始化為0,則求和的結果一定是錯誤的。
void main()
{ int I,a[10], sum=0; /*只要下邊要用,這個定義就必須要有,一般情況下也要有初始值*/
for(I=0;I<10;I++) sum+=a[I];
printf(「%d」,sum);
}
7、計算錯誤。主要注意:++,――和其它運算符一起運算時,除根據優先順序進行計算時,還要考慮先後位置的特殊含義;數據類型不一致時發生的自動轉換也會導致計算的誤差;還要注意求模結果的符號與被除數相同;某些特殊情況下使用懶惰求值法。
8、不能除以0,要做合法性檢查;
9、類型溢出。記住每種數據類型的取值范圍,確保數據在所定義類型範圍之內;
10、數學表達式的格式有誤。常見的有:(1)數學與C語言運算表達式的混淆(例如:=表示賦值,而= =才表示我們數學中的相等關系)。(2)、忽略了運算的優先順序。解決這個問題的最好方法就是寫數學表達式時不要從左到右,而是按優先順序的順序寫,寫完優先順序高的一個表達式後加上()再寫下一級的表達式,例如:計算梯形的面積時,要s=((a+b)*h)/2,不要1/2*a+b*h. (3)忽略了計算和賦值時的自動轉換。例如:float half=1/2;這樣,因為=右邊是整數相除的結果為整數0,不會得到0.5存入half,進而會影響下邊的計算結果。要想不在這兒絆跟頭,當計算不同類型的數據時,一定注意會不會出現引起錯誤的自動轉換,建議最好加上強制轉換。(4)賦值號左邊不是變數,例如:若有#define PI 3.14,程序中又出現PI=3.14159。又例如:f(n)=f(n-1)*n(這是典型的數學語言,在C語言中右邊的乘積不能正確存儲,而左邊又是一個函數調用)。
11、使用庫函數前忘了加#include<?.h>
二、流程式控制制
1、 丟掉語句結束標記「;」,尤其是for語句中表達式後或do-while語句後的分號,或在預處理命令後邊、while()後、for()後加「;」;
2、 If語句或循環語句中邏輯表達式或關系表達式書寫錯誤。一定要注意C語言的條件與數學表達式的區別(例如我們數學中經常寫到的0≤x≤9,在C語言中應該寫成x>=0&&x<=9)。
3、 if-else嵌套時不配對。最好在寫每個條件時要用兩個{}分別將兩個分支先括起來,再添加其中的語句,以保證其配對不易錯。
4、 switch()語句中的格式不正確。()中的表達式結果一定是一些明確的值,不能是區間;表達式的所有可能結果要列在case後邊,case與常量之間有一空格,不要丟掉必要的break;
5、 隨意修改循環控制變數i的值,導致循環次數的改變,尤其是當循環有嵌套時。在循環體中,不要將循環控制變數進行另外的改變。
6、 分不清什麼情況下用雙重循環,什麼情況下用兩個控制變數寫成一重循環。當I不變,j又循環一遍的時候用雙重循環。當I,j同時變化的時候用一重循環,此時,循環控制變數有兩個,但條件只寫一個就可以,因為另一個總是進行相應的變化的。
7、 忽略循環體與循環控制變數的關系。其實,很多情況下,循環控制變數都在循環體中起到非常重要的作用。應該利用上這種關系。
三、數組與指針
1、 字元串的輸入有錯誤:主要表現在使用scanf()或gets()時加了&,或輸入字元串時用循環,(這樣的話,字元個數無論多長,都不會為自動加\0,將來引用的時候也就不能以字元串的形式引用。)
2、 對字元串的處理中,循環條件仍然寫成I<N。由於字元串是不定長的,所以循環條件一般為str[I]!=』\0』 或I<strlen(str)
3、 而輸入所對應的變數是指針時(常見的有:輸入的變數是字元數組名或指向字元串的指針)不能加&。
4、 指針定義後未賦值就引用。如果在定義時不知道賦什麼值,可以用p=NULL賦初值,以避免引起的災難性錯誤。
5、 分不清p和*p。前者是指針,即地址,後者表示指針所間接引用的數據,但如果是二級指針或多級指針,取*以後得到的仍然可能是地址。
四、函數
1、 函數定義的時候,函數頭部加分號,而函數聲明的地方忘了加分號
2、 函數實參格式不對,主要表現在:給出實參時,多給出數組類型,或者,形參是數組int a[];的時候,給出的a[]或a[I].
3、 遞歸時忘了設置邊界條件,這樣易造成死循環調用。
4、使用函數之前未聲明(包括C庫函數的聲明)。建議大家,將所定義的一切函數都在程序開始的預處理命令後加上函數原型的聲明,這樣做不僅可以避免錯誤,而且整個程序的結構看起來更清楚。
五、結構體共用體
1、 結構體類型定義有誤,主要表現在:結構體類型里還有嵌套的時候,忘記了成員名稱。(例如:下邊的例子中,有些同學經常忽略了birthday)
2、 結構體類型名和結構體變數名混淆。例如:
struct STU
{….
Struct data
{int year,month,day;<br _extended="true"><br _extended="true">}birthday
};
struct STU a; struct STU是類型名稱,而且不分配空間,且不能直接引用。只有定義了結構體類型struct STU的變數a以後,才為a分配相應的內存空間,引用時也要是a.???
3、 結構體變數的成員引用不正確,尤其是當結構體類型中有嵌套定義的時候。一定要一級一級的引用。例如:上邊的例子:如果引用其中的年的話,一定是a.birthday.year.不能直接a.year.
4、 對結構體變數進行輸入輸出的時候,整體輸入或整體輸出。除作為函數參數外,不能對結構體變數整體操作,只能一個成員一個成員地輸入、輸出。
5、 不理解共用體的「共占內存」。對共用體中的成員變數,一定要靠一個標記區別它們,並分別按不同類型引用它們。切記:共用體變數不能做函數形參。
六、文件
1、 使用之前沒有打開文件,使用之後沒有關閉文件。
2、 相關函數的調用格式有誤。請一定注意實參的類型、順序、個數上與函數原型(或函數聲明)的一致
⑺ 何謂隱式類型轉換其轉換規則如何
數值的類型轉換分為強制性轉換(我們人為的轉換)和自動轉換(也就是隱式轉換,編譯器自己進行的轉換,不經我們的同意)
要想知道什麼是隱式轉換,那你首先得清楚數值共可以分為幾個類型,其中包括char=short<int<unsingned<long=float<double.他們的精確度是隨之增加的,他們能表示數值的范圍也是越來越大的。如果同類型的數值相操作(加減乘除等),是不會發生類型轉換,如果是不同類型數值相操作,比如說short型數值和int型數值相操作,那麼小取值范圍的類型(short)會先隱式轉換為取值范圍大的類型(int),然後再進行數值間的操作,得出來的結果也是int型。
我說道這里不知道你能否看懂。建議你看看譚浩強的《c程序設計》,裡面講的比較詳細。
⑻ C語言 數值類型隱式轉換的規則。幫忙看一下我理解的對嗎。
這個問題問題的好,是一個復雜的問題,只能簡單的按你的理解一起討論一下。有不同觀點
可以來 0x30網路貼吧直接發貼共同交流,網路知道不常在,可能會不能及時收到追問提示。
1、整數轉整數時, 將優先存放數據位的低位, 溢出的則拋棄. //未必
原因:有兩種情況小位元組的整數轉大位元組的整數,要看小位元組是有符號數還是無符號數。比如下面的代碼:
unsigned char ux = 0x80;
char x = 128;
int i = ux; //此時x為無符號的char,所以i的值為128
i = x; //此時x為有符號char,所以i的值為 -128
本質是有符號使用符號擴展,無符號使用0擴展。
大位元組的整數轉小位元組的整數,要看cpu的存儲順序。你說的只是intel平台上的,它是小端機,比如:
int i = 0x12345678;
char x = i;//在little endian的機器上,它的值是0x78如你所說,但是在big endian的機器上它將是0x12。
2、浮點轉整數時, 將優先存放數據位的高位(小數點之前的位), 小數點後丟棄.//可以設置丟棄方式
原因:浮點數轉整型數時,C/C++都是直接舍棄掉小數部分。比如
int i;
for (double f=1.0; (2.0 -f) >=FLT_EPSILON ; f+=0.1) {
i = f;
printf("%d\n", i); //不管你是1.0 還是1.9轉成整數都是1
}
但是這種舍棄規則是可以修改的,方法就是調用math.h中聲明的的floor()或者ceil(),前者是下行整型化,後者是上行整型化,換句話說,比如1.5floor(1.5) 它的值就是1
(下行整型化),ceil(1.5)就是2.0,這是上行整行化。
3、浮點轉浮點時, 將優先存放數據位的高位, 溢出的則拋棄.』(高精度轉低精度時將會進行四捨五入)
高精度轉低精度,C/C++標准未進行說明,有實現決定,vc++中是四捨五入。這種轉換,實際上沒有任何意義,因為數據丟失了。
低精度轉高精度,這個直接提升就好了。
4、整數轉浮點時, 將優先存放數據的低位, 溢出的則拋棄.
這個C/C++標准中也未進行說明,有實現決定。
⑼ 在 c語言中int long unsigned 和 char這四種類型數據的轉換規律是什麼
首先,在C中,數據之間的運算必須是同類型的才能進行運算。如果類型不一致,就必須先轉換成相同的類型----------由低級別 → 高級別轉換。
本題中,數據類型級別由低到高分別為:char→int→unsigned→long。轉換時由低級別向高級別轉換。
比如,有兩個數的數據類型分別為:char型跟long型。 就要先char轉換為long型(因為long級別比char高),再進行運算。
但是不能理解為:先將char轉換成int,再轉換成unsigned,再轉換成long。
⑽ c語言中,數據類型轉換前與轉換後數據的區別
數據類型轉換的一般格式為:(type_name)
expression
type_name為要轉換到的數據類型,expression為表達式。例如:
(float)
a;
//把a轉換為實型
(int)(x+y);
//把x+y的結果轉換為整型
(float)
100;
//將一個常量轉換為實型
【示例】將整數轉換為浮點數:
#include
<stdio.h>
int
main()
{
int
sum
=
17,
count
=
5;
double
mean;
mean
=
(double)
sum
/
count;
printf("Value
of
mean
:
%f\n",
mean);
return
0;
}
運行結果:
Value
of
mean
:
3.400000
需要注意的是,類型轉換運算符(
)的優先順序高於/,(double)
sum
/
count會先將
sum
轉換為
double
類型,然後再進行除法運算。如果寫作(double)
(sum
/
count),那麼運行結果就是
3.000000。
這種由程序員顯式進行的轉換稱為強制類型轉換。除了強制類型轉換,在不同數據類型的混合運算中編譯器也會隱式地進行數據類型轉換,稱為自動類型轉換。
自動類型轉換遵循下面的規則:
若參與運算的數據類型不同,則先轉換成同一類型,然後進行運算。
轉換按數據長度增加的方向進行,以保證精度不降低。例如int型和long型運算時,先把int量轉成long型後再進行運算。
所有的浮點運算都是以雙精度進行的,即使僅含float單精度量運算的表達式,也要先轉換成double型,再作運算。
char型和short型參與運算時,必須先轉換成int型。
在賦值運算中,賦值號兩邊的數據類型不同時,需要把右邊表達式的類型將轉換為左邊變數的類型。如果右邊表達式的數據類型長度比左邊長時,將丟失一部分數據,這樣會降低精度。