三個問題

問題一:
不同數據類型之間強制轉換
float b;
printf(“%d”,(int)b );
可用(數據類型),強制轉換後打印
如: int sum = 17, count = 5;
double mean;
mean = (double) sum / count;

long/short可以修飾int,long還可以修飾double。
unsigned/signed可以修飾int, char,不可以修飾浮點型。
int長度是機器的字長,short int是半個字長,long int是一個或兩個字長。
unsigned/signed長度與普通類型一樣,只是表示區間不同。

下圖表示了類型自動轉換的規則:

自動類型轉換遵循下面的規則:
若參與運算的數據類型不同,則先轉換成同一類型,然後進行運算。
轉換按數據長度增加的方向進行,以保證精度不降低。例如int型和long型運算時,先把int量轉成long型後再進行運算。
所有的浮點運算都是以雙精度進行的,即使僅含float單精度量運算的表達式,也要先轉換成double型,再作運算。
char型和short型參與運算時,必須先轉換成int型。
在賦值運算中,賦值號兩邊的數據類型不同時,需要把右邊表達式的類型將轉換爲左邊變量的類型。如果右邊表達式的數據類型長度比左邊長時,將丟失一部分數據,這樣會降低精度。

問題二:
二維數組的指針實現
二維數組元素a[i][j]可表示成(a[i]+j)或((a+i)+j), 它們都與a[i][j]等價, 或者還可寫成((a+i))[j]。
如 : int a[3][4];
int *a=a;
*(a[1]+0)=a[1][0];
((a+1)+0)=a[1][0];
第2行的第1個元素

    ┏━━━━┓    ┏━┳━┳━┳━┓ 

a─→ ┃ a[0] ┃─→ ┃0 ┃1 ┃2 ┃3 ┃
┣━━━━┫ ┣━╋━╋━╋━┫
┃ a[1] ┃─→ ┃4 ┃5 ┃6 ┃7 ┃
┣━━━━┫ ┣━╋━╋━╋━┫
┃ a[2] ┃─→ ┃8 ┃9 ┃10┃11┃
┗━━━━┛ ┗━┻━┻━┻━┛

一. 二維數組元素的地址
爲了說明問題, 我們定義以下二維數組:
int a[3][4]={{0,1,2,3}, {4,5,6,7}, {8,9,10,11}};
a爲二維數組名, 此數組有3行4列, 共12個元素。但也可這樣來理解, 數組a由三個元素組成: a[0], a[1], a[2]。而它中每個元素又是一個一維數組, 且都含有4個元素 (相當於4列), 例如, a[0]所代表的一維數組所包含的 4 個元素爲 a[0][0], a[0][1], a[0][2], a[0][3]。如圖1.所示:
┏━━━━┓ ┏━┳━┳━┳━┓
a─→ ┃ a[0] ┃─→ ┃0 ┃1 ┃2 ┃3 ┃
┣━━━━┫ ┣━╋━╋━╋━┫
┃ a[1] ┃─→ ┃4 ┃5 ┃6 ┃7 ┃
┣━━━━┫ ┣━╋━╋━╋━┫
┃ a[2] ┃─→ ┃8 ┃9 ┃10┃11┃
┗━━━━┛ ┗━┻━┻━┻━┛
圖1.

                圖1. 

但從二維數組的角度來看, a代表二維數組的首地址, 當然也可看成是二維數組第0行的首地址。a+1就代表第1行的首地址, a+2就代表第2行的首地址。 如果此二維數組的首地址爲1000, 由於第0行有4個整型元素(每個整型元素佔2字節), 所以a+1爲1008, a+2 也就爲1016。如圖2.所示
a[3][4]
a ┏━┳━┳━┳━┓
(1000)─→┃0 ┃1 ┃2 ┃3 ┃
a+1 ┣━╋━╋━╋━┫
(1008)─→┃4 ┃5 ┃6 ┃7 ┃
a+2 ┣━╋━╋━╋━┫
(1016)─→┃8 ┃9 ┃10┃11┃
┗━┻━┻━┻━┛
圖2.
既然我們把a[0], a[1], a[2]看成是一維數組名, 可以認爲它們分別代表它們所對應的數組的首地址, 也就是講, a[0]代表第 0 行中第 0 列元素的地址, 即&a[0][0], a[1]是第1行中第0列元素的地址, 即&a[1][0], 根據地址運算規則, a[0]+1即代表第0行第1列元素的地址, 即&a[0][1], 一般而言, a[i]+j即代表第 i行第j列元素的地址, 即&a[i][j]。
另外, 在二維數組中, 我們還可用指針的形式來表示各元素的地址。如前所述, a[0]與(a+0)等價, a[1]與(a+1)等價, 因此a[i]+j就與*(a+i)+j等價, 它表示數組元素a[i][j]的地址。
因此, 二維數組元素a[i][j]可表示成(a[i]+j)或((a+i)+j), 它們都與a[i][j]等價, 或者還可寫成((a+i))[j]。
另外, 要補充說明一下, 如果你編寫一個程序輸出打印a和*a, 你可發現它們的值是相同的, 這是爲什麼呢? 我們可這樣來理解: 首先, 爲了說明問題, 我們把二維數組人爲地看成由三個數組元素a[0], a[1], a[2]組成, 將a[0], a[1], a[2]看成是數組名它們又分別是由4個元素組成的一維數組。因此, a表示數組第 0行的地址, 而*a即爲a[0], 它是數組名, 當然還是地址, 它就是數組第0 行第0
列元素的地址。

二. 指向一個由n個元素所組成的數組指針
在Turbo C中, 可定義如下的指針變量:
int (*p)[3];
指針p爲指向一個由3個元素所組成的整型數組指針。在定義中, 圓括號是不能少的, 否則它是指針數組。這種數組的指針不同於前面介紹的整型指針, 當整型指針指向一個整型數組的元素時, 進行指針(地址)加1運算, 表示指向數組的下一個元素, 此時地址值增加了2(因爲放大因子爲2), 而如上所定義的指向一個由3個元素組成的數組指針, 進行地址加1運算時, 其地址值增加了6(放大因子爲2x3=6), 這種數組指針在Turbo C中用得較少, 但在處理二維數組時, 還是很方便的。例如:
int a[3][4], (*p)[4];
p=a;
開始時p指向二維數組第0行, 當進行p+1運算時, 根據地址運算規則, 此時放大因子爲4x2=8, 所以此時正好指向二維數組的第1行。和二維數組元素地址計算的規則一樣, p+1指向a[0][1], (p+i)+j則指向數組元素a[i][j]。

備註:
int a[10][20]; //真正的二維數組

int *b[10]; //定義分配了10個指針,沒有初始化。換句話說,b是一個由10個整型(int)指針構成的指針數組。
int (*p)[3]; //指向數組的指針

int *p(); //p是一個函數,返回值是一個int型指針
int (*p)(); //指向函數的指針

float **p; // p不是二維數組的指針,而是指向指針的指針,即二級指針。

不同數據類型的放大因子等於一個該數據類型的變量所佔用的內存單元數

問題三:
如果爲short型,用什麼格式打印
在int的格式前加h
short int ; 則打印 “%hd”
short 對應的%h
unsigned short 對應%hu(十進制) %ho(八進制) %hx(十六進制)

unsigned short d ;
printf(“d = %u\n”,d);
輸出unsigned short ,unsigned int 一般用 %u
u 爲無符號的十進制整數
像unsigned long 輸出的話一般用%lu

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章