基本型別轉換規則和sizeof的用法
一.大範圍資料向小範圍轉換時的規則:
1.在轉換時和自身的型別有關和目標型別無關,,有符號的擴充符號位,無符號的擴充0.
#include<stdio.h>
int main()
{
char c = 128;
unsigned char uc = 128;
unsigned short us = 0;
us = c+uc;
printf("%x\n",us);
us = (unsigned char)c + uc;
printf("%x\n",us);
us = c + (char)uc;
printf("%x\n",us);
return 0;
}
結果為:
0
100
ff00
過程;
1111 1111 1000 0000 0000 0000 1000 0000 1111 1111 1000 0000
+ 0000 0000 1000 0000 + 0000 0000 1000 0000 + 1111 1111 1000 0000
10000 0000 0000 0000 0000 0001 0000 0000 1 1111 1111 0000 0000
0 0 0 0 0 1 0 0 f f 0 0
二.用法
sizeof(型別說明符,陣列名或表示式);或sizeof 變數名
1. 定義:
sizeof是C/C++中的一個操作符(operator),簡單的說其作用就是返回一個物件或者型別所佔的記憶體位元組數。
2. 語法:
sizeof有三種語法形式,如下:
1) sizeof( object ); // sizeof( 物件 );
2) sizeof( type_name ); // sizeof( 型別 );
3) sizeof object; // sizeof 物件;
例如
int i;
sizeof( i ); // ok
sizeof i; // ok
sizeof( int ); // ok
sizeof int; // error
3. sizeof的常量性
sizeof的計算髮生在編譯時刻,所以它可以被當作常量表達式使用,如:
char ary[ sizeof( int ) * 10 ]; // ok
4. 基本資料型別的sizeof
這裡的基本資料型別指short、int、long、float、double這樣的簡單內建資料型別,由於它們都是和系統相關的,所以在不同的系統下取值可能不同,這務必引起我們的注意,儘量不要在這方面給自己程式的移植造成麻煩。
一般的,在32位編譯環境中,sizeof(int)的取值為4。
陣列的sizeof值等於陣列所佔用的記憶體位元組數,如:
char a1[] = "abc";
int a2[3];
sizeof( a1 ); // 結果為4,
sizeof( a2 ); // 結果為3*4=12(依賴於int)
前面已經說過,位域成員不能單獨被取sizeof值,我們這裡要討論的是含有位域的結構體的sizeof,只是考慮到其特殊性而將其專門列了出來。
C99規定int、unsigned int和bool可以作為位域型別,但編譯器幾乎都對此作了擴充套件,允許其它型別型別的存在。使用位域的主要目的是壓縮儲存,其大致規則為:
1) 如果相鄰位域欄位的型別相同,且其位寬之和小於型別的sizeof大小,則後面的欄位將緊鄰前一個欄位儲存,直到不能容納為止;
2) 如果相鄰位域欄位的型別相同,但其位寬之和大於型別的sizeof大小,則後面的欄位將從新的儲存單元開始,其偏移量為其型別大小的整數倍;
3) 如果相鄰的位域欄位的型別不同,則各編譯器的具體實現有差異,VC6採取不壓縮方式,Dev-C++採取壓縮方式;
4) 如果位域欄位之間穿插著非位域欄位,則不進行壓縮;
5) 整個結構體的總大小為最寬基本型別成員大小的整數倍。
還是讓我們來看看例子。
示例1:
struct BF1
{
char f1 : 3;
char f2 : 4;
char f3 : 5;
};
其記憶體佈局為:
|_f1__|__f2__|_|____f3___|____|
|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
0 3 7 8 1316
位域型別為char,第1個位元組僅能容納下f1和f2,所以f2被壓縮到第1個位元組中,而f3只
能從下一個位元組開始。因此sizeof(BF1)的結果為2。
示例2:
struct BF2
{
char f1 : 3;
short f2 : 4;
char f3 : 5;
};