C++字符串輸入輸出以及複合類型淺談

在這裏插入圖片描述



1. 字符和字符串

第一種創建字符串的方法:

int main()
{
 char ch_1[] = { 'f','d','o','g' };
 char ch_2[] = { 'f','d','o','g','\0' };
 cout << ch_1 << endl;
 cout << ch_2 << endl;
}

在這裏插入圖片描述
ch_1和ch_2都是char字符數組,但是ch_2擁有字符串特有的\0,所以ch_2也被稱爲字符串,而ch_1由於沒有\0,所以不能成爲字符串。
想要使用cout輸出兩個字符數組,第二個被正常輸出,第一個正常輸出後出現了亂碼,處理字符串的函數,像cout輸出字符串,它們都會把字符串裏面的字符一個一個的進行處理,如果遇到空字符,則停止處理,由於第一種寫法沒有寫入\0,所以cout會一直處理,直到在內存中遇到空字符,好在內存中存在很多的空字符,所以纔會出現上述情況。

好了,上面這種瞭解瞭解就好,要是一個字符一個字符輸入,不得累死!我們看更高級一點的:

char ch[]="Fodg"; 

使用引號括起來的一串字符,會自動添加\0並隱藏,併成爲字符串,並且,C++會將從鍵盤得到的一串字符自動添加\0成爲字符串。

字符串常量(使用雙引號)不能與字符常量(使用單引號)互換,看下面:

 char c = "a";//這種寫法是錯誤的
 char * c = "a"; //這種寫法是正確的,可以證明"a"的實質是地址

在這裏插入圖片描述
下面纔是重頭戲,C++是面向對象的一門編程語言,那怎麼能沒有類,既然有類,怎麼能沒有String,學習過面向對象的人應該都知道string的方便。

#include<string> //記得要包含頭文件
 string str_1 = "花狗";
 cout << str_1<<endl;
 cin >> str_1;
 cout << str_1[0];
 cout << str_1[1] << endl;

運行結果:
在這裏插入圖片描述
各位記得要輸出str_1[0]和str_1[1],還記不記得中文是用連個字節存儲的,只輸出一個是無法顯示完整漢字的,這裏要千萬注意。
C++新增的string方便遠遠不及於此,往下看。

string字符串的拼接:

string str_1 = "花狗";
string str_2 = "Fdog";
string str_3 = str_1+str_2;

運行結果:
在這裏插入圖片描述
這種技術叫做運算符重載,C++將+進行重載,後面我們會學習到。

string字符串的附加:

string str_1 = "花狗";
string str_2 = "Fdog";
str_2 += str_1;
cout<<str_2;

運行結果:
在這裏插入圖片描述
篇幅有限,有關字符串的深入,將另外說明。


2. 結構體

聲明結構體使用struct關鍵字,創建形式如下:

struct student
{
     //這裏可以添加C++基本類型
};//注意分號,很多初學者會把分號忘記

創建結構體有什麼用呢?舉一個不太恰當的例子:

C++是面向對象的一門語言,比如人就是一個對象,人這個對象有屬性,比如姓名,性別,年齡,這些單個的屬性我們都可以使用特點的基礎類型去定義,例如姓名,可以用char name[10],年齡可以使用int類型去定義,這都是沒有問題的。但是如果有500個人需要存儲他們的屬性,難道我們要創建500個char 500個int?假如他們的的屬性不止三項這樣,分開存儲確實可以,但是人們希望有一種數據類型,可以存儲每個人的所有屬性,進行統一管理,互不相干,於是struct就誕生了,

struct student
{
   char name[10];   //姓名存儲
   char sex[10];    //性別存儲
   int age;         //年齡存儲
};
int main()
{
    struct student s1;
    s1.age = 21;
    //s1.name = "花狗";
    //s1.sex = "男"; 這裏出現了錯誤,提示表達式必須是可修改的左值。
    //這是爲什麼呢?原因是數組的初始化規則,它們限制了初始化的時刻,決定了數組的元素數目與初始化
    //器中的值的數目不相同時將發生的情況,例如下面:
    char name[10] = "花狗";//這是被允許的
    char name1[10];
    //name = "花狗"; 這是不被允許的
    //但是可以如下的方法爲結構體賦值
    //第一種:
    struct student s2 = { "花狗","男",21 };
    student s3{ "大頭","男",21 }; //和C語言不同,C++允許用戶省略struct關鍵字,並且等號也是可省略的
    //第二種:
    student s4 = {
                   "小頭",
                   "女",
                   21
                 };//要注意最後的分號
 //上述使用的是靜態數組,我們並不能保證name[10]是否能存儲下其他名字,
 //如果定義爲name[100]倒是可以存儲名字,不必擔心溢出
 //但是也浪費內存空間,更爲高級的一種方法是動態數組,
 //name需要多少內存由用戶輸入的內容大小決定並自行申請內存。後面會講。
}

上述使用的是靜態數組,我們並不能保證name[10]是否能存儲下其他名字,如果定義爲name[100]倒是可以存儲名字,不必擔心溢出,但是也浪費內存空間,更爲高級的一種方法是動態數組, name需要多少內存由用戶輸入的內容大小決定並自行申請內存。後面會講。


結構體更爲高級的用法是:

typedef struct student
{
 char name[10]; //姓名存儲
 char sex[10];    //性別存儲
 int age;       //年齡存儲
}student_1,*student_1;

在C語言中,想要使用結構體變量,必須使用struct,如果不想使用struct,則可以使用typedef關鍵字爲struct stdent 起一個別名,也就是student_1。
雖然C++中不需要起別名也可以省略,但應該知道typedef這個關鍵字,至於*student_1,是定義了一個結構體指針,關於指針,這裏不再多說,只需知道有這種寫法。


3. 共用體

共用體和結構體的聲明或者說定義方式是一樣的,只是關鍵字不一樣:

 union world
{
 short short_val;
 int int_val;
 long long_val;
};
//怎麼理解共用體呢,它是能像結構體一樣存儲不同類型的數據,但是同一時間只能存儲其中的一種,比如我定義了一個共用體對象
//這個對象同時只能在同一時間使用共用體中的一種數據,

//world a = { 78,78,78L };//這是錯誤的用法,會提示初始值太多
 world b;
 b.int_val = 12;
 b.long_val = 21L;
 b.short_val = 33;
 cout << b.int_val;//結果不確定,b現在只有short_val的值

4. 結構體和共用體的佔地面積(在內存中大小)

寫完結構體和共用體,來看看它們所佔的內存爲多少:
結構體:

 struct student
{
 char name[10]; //姓名存儲
 char sex[10];    //性別存儲
 int age;       //年齡存儲
};

共用體:

 union world
{
 short short_val;
 int int_val;
 long long llong_val;
};
cout << sizeof(student) << endl;
 cout << sizeof(world) << endl;

運行結果:
在這裏插入圖片描述
結構體10+10+4爲24,這個沒有任何疑問,而共用體只有8,這也是其名字的來源,共用,就是共用一塊內存,但其要保證其內存爲其中數據類型的最大值,也就是long long類型的大小。

複合類型:由基本類型爲基礎,創建的像結構體,共用體便是複合類型,複合類型也是一種數據結構,它還可以和其他的複合類型所構造,
只不過這類類型需要用戶根據自身需求定義罷了。

5. 枚舉

C++的enum工具提供了另一種創建符號常量的方法,這種方法可以替代const,而且還允許定義新類型。
語法如下:

enum color {red,yellow,blue};
// color是新類型的名稱,red,yellow,blue將作爲符號常量,它們對應的值爲0,1,2,依次遞增。
// 也可以顯式的自定義符號常量的值:
//enum color {red=3,yellow=2,blue=1};
//自定義的值必須是整形。

color a;
a = red; // 正確
a = 3; //不可以,3是非enum值,
// 對於枚舉,C++只定義了賦值運算符,並沒有爲枚舉定義算術運算符,但是,
//如果執行下面操作,枚舉將會被轉換爲int類型
int b = red+1;

枚舉的取值範圍:
首先找到枚舉最大值和最小值,找到大於值最小值的2的冪,將它減去1,得到的便是取值範圍的上線,例如某枚舉最大值爲101,在2的冪比這個數大的是128,減1爲127,這個127就是這個枚舉的上限,如果枚舉的最小值不小於0,那麼0就是枚舉的下限,如果最小值小於0,則採用上述方法,例如最小值爲-6,比它小的2的冪爲8,8-1爲7,但要加上負號爲-7,這便是下限。


6. 靜態數組和動態數組(需要創建指針)

int main()
{
 //比如我要記錄一個班的成績,拿靜態數組來做的會是這個樣子:
 int num[100];//這裏這個100是我自己估算的,我也不知道這個班會有多少人,有可能10個,有可能200個,
              //所以靜態數組只適用於在編譯之前就已經確定了的數值
 //如果使用動態數組,我們可以有一個人頭,加一個人頭,不再擔心內存空間浪費。
 int * num = new int[10];
 //這句話的意思是申請20個字節的內存用來存放int數據,這就是動態數組,與之隨行的是delete。
 //delete用於釋放申請的內存。
}

下面用一個例子說明使用動態數組的好處:

int main()
{
    int num = -1;
    int * number = NULL;
    while (num)
    {
        cout << "請輸入同學的年齡:" << endl;
        cin >> num;
        if (num > 0)//當輸入負數則停止
        {
            number = new int[0];//申請一個int大小的內存存放num
        }
        else
        {
            return 0;
        }
    }
    delete number;
}

在這裏插入圖片描述
當使用動態數組時不用考慮數量問題,這就是使用動態數組的好處。由於篇幅有限,有關動態數組的高級應用以及期間需要主要的問題,我們另起一篇詳談。


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