06.複合資料型別
06.複合資料型別
字元
字元型別、字元文字與量
定義格式:char ch; const char cch = 'C';
字元文字使用單引號對
實際儲存時字元型別量儲存字元的對應ASCII值
可使用signed與unsigned修飾字符型別
單字元用8個位元組儲存,表達範圍-128127,用unsigned修飾的話範圍為0255
字元表示的等價性
char a = 'A';
char a = 65; //ASCII值
char a = 0101; //八進位制
char a = 0x41; //十六進位制
ASCII碼錶
控制字元、通訊專用字元、可列印字元
回車與換行
Windows: \n\r
Linux:\n
Mac: \r
ASCII使用示例:
判斷某個字元是否為數字
bool isDigit(char c)
{
if(c >= '0' && c <= '9') //等價於if(c >= 48 && c <= 57)
return true;
else
return false;
}
將字元轉換為大寫字元
char ToUpperCase(char c) { if(c >= 'a' && c <= 'z') return c - 'a' + 'A'; //等價於return c + 32; else return c; }
C標準字元特徵庫:ctype.h/cctype
,標準字元特徵庫常用函式:bool isalnum(char c);bool isalpha(char c);bool isdigit(char c);bool islower(char c);bool isspace(char c);bool isupper(char c);char tolower(char c);char toupper(char c);
陣列
陣列的意義與性質
陣列的定義
定義格式:元素型別 陣列名稱[常數表示式];
示例:int a[8]; //定義包含8個整數元素的陣列
特別說明
常數表示式必須是常數和常量,不允許為變數
錯誤示例:
int count = 8; int c[count];
陣列元素編號從0開始計數,元素訪問格式為a[0],a[1],a[2]...
不允許對陣列進行整體賦值操作,只能使用迴圈逐一賦值元素
錯誤示例:int a[8], b[8]; a = b;
意義與性質
將相同性質的資料元素組織成整體,構成單一維度上的資料序列
陣列的儲存表示
陣列元素一次連續存放,中間沒有空閒空間
陣列的地址
陣列的基地址:陣列開始儲存的物理位置
陣列首元素的基地址:陣列首個元素開始儲存的實體地址,數值上總是與陣列基地址相同
“&”操作符:&a獲得陣列的基地址;&a[0]獲得陣列首元素的基地址
設陣列基地址為p,並設每個元素的儲存空間為m,則第i個元素的基地址為p+mi
陣列元素的初始化
基本初始化格式
定義格式:元素型別 陣列名稱[元素個數] = {值1, 值2, 值3, ……};
示例:int a[8] = {1, 2, 3, 4, 5, 6, 7, 8};
初始化時忽略元素個數表示式
在全部元素均初始化時可以不寫元素個數,使用sizeof操作符可以獲得元素個數
示例:int a[] = {1, 2, 3, 4, 5, 6, 7, 8}; int num_of_elements = sizeof (a) / sizeof (a[0]);
sizeof獲取陣列儲存空間大小(以位元組為單位),sizeof(a[0])獲取陣列首元素的儲存空間大小。
陣列元素的訪問
陣列與函式
陣列元素作為函式實際引數
int Add(int x, int y) {return (x + y);}
int a[2] = {1, 2}, sum;
sum = Add(a[0], a[1]);
陣列整體作為函式形式引數
陣列整體作為函式形式引數
基本格式:返回值型別 函式名稱 (元素型別 陣列名稱怕[], 元素個數型別 元素個數)
示例:void GenerateIntegers(int a[], unsigned int n);
特別說明:作為函式形式引數時,陣列名稱後的中括號內不需列寫元素個數,必須使用單獨的引數傳遞元素個數資訊
陣列作為函式引數時有個巨大的優勢,是能夠將函式內部對陣列元素的修改帶出函式以外,能對陣列產生實際改變。即陣列作為函式引數時既是輸入的一部分也是輸出的一部分。
示例:
隨機產生n個介於[lower,upper]之間的整數並儲存在陣列中
void GenerateIntegers(int a[],unsigned int n, int lower, int upper)
{
unsigned int i;
for(i = 0;i < n;i++)
a[i] = GenerateRandomNumber(lower,upper);
}
上述程式碼中,對a[]陣列的實際操作真正反映到了a[]中。同時需注意,C++中陣列宣告時陣列元素個數必須為常數或常量(C中只能為常數),所以需額外傳一個引數n表示陣列元素個數,而不能將元素個數寫死或直接宣告a[n]。
上述問題的完整描述:使用單獨陣列名稱作為函式實際引數,傳遞陣列基地址而不是陣列元素值;形式引數與實際引數使用相同儲存區,對陣列形式引數值的改變會自動反應到實際引數中
多維陣列
多維陣列的定義
定義格式:元素型別 陣列名稱[常數表示式1] [常數表示式2] ...;
示例一:int a[2][2]; //2*2的整型二維陣列
示例二:int b[2] [3] [4] ; //2*3*4的整型三維陣列
多維陣列的初始化
與一維陣列類似:int a[2][3] = {1, 2, 3, 4, 5, 6};
單獨初始化每一維:int a[2][3] = {{1, 2, 3}, { 4, 5, 6} };
多維陣列的儲存佈局
同一維陣列,先行後列儲存。
結構體
結構體的意義與性質
結構體的意義
與陣列的最大差別:不同型別資料物件構成的集合
當然也可以為相同型別的但具體意義或解釋不同的資料物件集合
結構體型別的定義:注意型別定義後面的分號
struct 結構體名稱
{
成員型別1 成員名稱1;
成員型別2 成員名稱2;
......
成員型別3 成員名稱3;
};
示例
日期結構體
struct DATE
{
int year;
int month;
int day;
};
複數結構體
struct COMPLEX
{
double real;
double imag;
};
結構體型別的宣告
僅僅引入結構體型別的名稱,而沒有給出具體定義,其具體定義在其他標頭檔案中或本檔案後續位置
如何表示學生資訊?
成員:整數型別的學號id、字串型別的姓名name、性別(單獨定義列舉型別)gender、年齡age、字串型別的地址addr
enum GENDER{FEMALE,MALE};
struct STUDENT
{
int id;
STRING name; //假設已有字串型別的定義
GENDER gender;
int age;
STRING addr;
};
結構體的儲存表示
按照成員定義順序存放
各成員的儲存空間一般連續
特殊情況
因為不同硬體和編譯器的原因,不同型別的成員可能會按照字(兩個位元組)或雙字(四個位元組)對齊後存放
使用sizeof獲得結構體型別量佔用空間大小(以位元組為單位),下述兩種方式均可:sizeof date;
sizeof(date);
結構體資料物件的訪問
結構體型別的變數與常量:按普通量格式定義
示例一:DATE date;
示例二:STUDENT zhang_san;
示例三:STUDENT students[8];
結構體量的初始化
示例四:DATE date = {2008, 8, 8};
結構體量的賦值
與陣列不同,結構體量可直接賦值,拷貝過程為逐成員一一複製
示例五:DATE new_date; new_date = date;
結構體成員的訪問
使用點號操作符(成員選擇操作符)“."解析結構體量的某個特定成員
示例一:DATE date; date.year = 2008; date.month = 8; date.day = 8;
巢狀結構體成員的訪問
可以連續使用點號逐層解析
示例二:
struct FRIEND{int id; STRING name; DATE birthday;};
FRIEND friend;
friend.birthday.year = 1988;
複雜結構體成員的訪問
FRIEND friends[4];
friends[0].birthday.year = 1988;
結構體與函式
編寫一函式,使用結構體型別儲存日期,並返回該日在該年的第幾天資訊,具體天數從1開始計數,例如2016年1月20日返回20,2月1日返回32
unsigned int GetDateCount(DATE date)
{
static unsigned int days_of_months[13]=
{0,31,28,31,30,31,31,31,31,30,31,30,31};
unsigned int i, date_id = 0;
for(i = 1;i < date.month;i++)
date_id += days_of_months[i];
date_id += date.day;
if(date,month > 2 && IsLeap(date.year))
date_id++;
return date_id;
}