1. 程式人生 > >研一寒假03_string定義字符串_指著(2)_指針&動態結構

研一寒假03_string定義字符串_指著(2)_指針&動態結構

函數 出現 問題 種類 功能 編輯 數組 內存 ***

#---------------------------string定義字符串-----------------------------#

#include <iostream>
#include <string> //for string class available 要使用string去定義變量,必須包含這個頭文件
//要使用string類,必須包含string這個頭文件.string類位於名稱空間std中,因此還必須提供一條using編譯指令,或者使用std::string來引用它
#include <cstring> //c-style string library

int main()
{
using namespace std;
string str1; //定義一個空的字符串變量str1
string str2="panther"; //定義一個字符串變量str2,string有自動調整字符數大小的功能,string類隱藏了字符串數組的性質

string str3=str2; //將str2復制給str3

char ch1=str2[2]; //將str2的第三個字母賦值給ch1,即可以用數組表示方法來訪問存貯在string對象中的字符

/* string可以用於輸入和輸出 */
cin>>str1; //可以用cin從鍵盤輸入字符串至str1

cout<<str2; //可以用cout來顯示string對象

string str4=str2+str3; //將str2和str3加在一起賦值給str4 即str4=pantherpanther

/* c風格和c++風格計算字符個數的方法 */
/* 註意strlen()從數組的第一個元素開始計算字節數,直到遇到空字符 */
int len1=str2.size(); //計算str2字符的個數,並賦值給len1;str2是一個string對象,而size()是string對象的一個方法,故可以用這種表示方法

char ch2[20]="jaguar"; //創建一個字符串數組
int len2=strlen(ch2) //strlen()用於c風格去計算數組中字符的個數

/* c++風格輸入行的方法(即每次不是只輸入一個單詞) */
char ch3[20]; //創建一個空字符串數組ch3
string str5; //創建一個空的字符串變量str5

cin.getline(ch3,20); //c-style 輸入行的方法
getline(cin,str5); //c++風格輸入行的方法,getline()不是淚方法,它將cin作為參數指出到哪裏去尋找輸入
//為何char類型的可以用cin.getlline()而string類型的缺不可以?這是由於在引入sring類之前,c++有了istream類,因此istream的設計考慮了諸如
//int char doule等基本的數據類型,但是沒有考慮string類,所以istream中有處理int double等的基本類方法,但是沒有string對象的類方法

return 0;
}

#include <iostream>
#include <string>

int main()
{
std::string name; //將name的類型聲明為std::string
string str1="haijing";
}

#--------------------------指針(2)---------------------------#

#include <iostream>
#include <cstring> //for strlen(),strcpy()

int main()
{
using namespace std;


/* 指針加1的問題 */

int p1=3;
double* pw; //聲明一個指針

p1=p1+1; //p1=4
pw = pw+1; //如果系統對double型變量使用8個字節存儲,則pw在原來的基礎上加8(地址加8,實際pw指向下一個元素)


/* 數組和指針的關系 */

double wages[3] = {1000.0,2000.0,3000.0}; //聲明並初始化一個數組
short stacks[3] = {3,2,1}; //聲明並初始化一個數組 short占兩個字節
double* pd=wages; //或者double* pd=&wages[0];是等價的,都是講數組wages第一個元素的地址賦給pd

cout<<stacks[1]<<endl; //打印stacks數組的第二個元素2
cout<<*(stacks+1)<<endl; //打印stacks數組的第二個元素2 即stacks[1]和*(stacks+1)是等價的
//在程序中寫stacks[1]的時候,c++編譯器會將stacks[1]表達式看作是*(stacks+1)。同樣stacks[1]和*(stacks+2)是等價的

cout<<sizeof(wages)<<endl; //打印24 在使用sizeof的時候,c++編譯器不會將wages解釋為數組第一個元素的地址,在這裏有三個元素,一個元素占8個字節,所以一共是24字節
cout<<sizeof(pd)<<endl; //打印4

cout<<&wages[0]<<endl; //或者是 cout<<wages<<endl; 都將打印數組元素的第一個地址
cout<<&wages<<endl; //打印整個數組的地址

/* 指針和字符串(引入) */

char flower[10] = "rose";
cout<<flower<<"s are beautiful\n"; //打印roses are beautiful\n
//註意在cout和多數c++中,char數組名、char指針以及用引號括起來的字符串常量都被解釋為字符串第一個字符的地址*****
//如果給cout一個 字符 的地址,那麽cout將從改字符開始打印,直到遇到空字符\0
//但是上述代碼並不會吧真個字符串的地址發給cout,而只是發送第一個字符的地址給cout,這意味著對於數組中的字符串、用引號括起來的
//字符常量以及指針所描述的字符串。處理的方式都是一樣的,都將傳送第一個字符的地址


/* 指針和字符串(代碼) */

char animal[20]="bear"; //聲明並初始化一個數組
const char* bird = "wren"; //聲明並初始化一個字符串常量指針,因為有const所以不可以更改bird所指向的值,即不能對bird使用cin輸入
//該語句將w的地址賦給bird
char* ps; //聲明一個指針,沒有初始化

cout<<animal<<" and "; //打印bear and
cout<<bird<<"\n"; //打印wren,最後的\n表示換行
//cout<<ps<<"\n"; //錯誤,因為並沒有對ps初始化

cout<<"Enter a kind of animal: ";
cin>>animal; //輸入至animal數組中,而不能輸入到bird中,因為在定義bird時使用了const,所以只能讀bird而不能修改
//也不能輸入至ps,因為ps沒有被初始化,輸入到哪裏都不知道
//此句會覆蓋animal中原有的內容?書中給出的答案是會覆蓋掉 如果輸入的是fox
ps = animal; //設置ps指向一個字符串 將animal數組中第一個元素的地址賦給ps
cout<<animal<<" at "<<(int *) animal<<endl; //打印fox at 0x0065fd30 animal原來的類型是char*,這裏做強制轉換int*
cout<<ps<<" at "<<(int *) ps<<endl; //打印fox at 0x0065fd30 ps原來的類型是char*
//一般來說,如果給cout提供一個指針,cout將會打印一個地址,但如果指針的類型為char*,那麽cout將顯示指向的字符
//如果要顯示字符串的地址,則將該指針強制轉換為另一種類型,如int*,因此ps顯示的是fox,而(int*)ps顯示的是地址

char* pf;
pf=new char [strlen(animal)+1]; //使用new給pd分配一個長度為animal的長度+1的內存地址
strcpy(pf,animal); //將animal復制給pf, 經常需要將字符串放到數組中,在數組初始化時可以使用等號(=),在不是初始化的時候,就只能使用strcpy()或者是strncpy()了
//所以對字符串進行操作時,最好使用string去定義變量,之後就可以使用+來進行字符串的合並了*****
cout<<"After using strcpy():\n";
cout<<animal<<" at "<<(int*)animal; //顯示fox at 0x0065fd30
cout<<pf<<" at "<<(int*)pf<<endl; //顯示fox at 0x004301c8

return 0;
}

#-----------------------------------------指針&動態結構--------------------------------------#

#include <iostream>

/* 新建一個結構 */
struct inflatable
{
char name[20];
float volume;
double price;
};

/* 主函數 */
int main()
{
using namespace std;

inflatable* ps = new inflatable; //把可以存儲inflatable結構的一塊可用內存的地址賦給ps
//創建動態結構,在程序運行時候創建結構
//由於沒有結構變量,c++提供了->來訪問結構成員 方法一是:ps->price=3.99對結構的price成員進行賦值
//方法二:如果ps是指向結構的指針,則*ps就是被指向的值--結構本身,由於*ps是一個結構,因此(*ps).price是該結構的price成員

cout<<"Enter name of inflatable item: ";
cin.get(ps->name,20); //使用get方法輸入行,可以輸入20個字符給結構中的name成員,第一種給結構成員賦值方法

cout<<"Enter volume in cubic feet: ";
cin>>(*ps).volume; //第二種給結構成員賦值方法

cout<<"Enter price: $";
cin>>ps->price; //第一種給結構成員賦值方法

cout<<"Name: "<<(*ps).name<<endl;
cout<<"Volume: "<<ps->volume<<endl;
cout<<"Price: "<<ps->price<<endl;

delete ps; //釋放空間

return 0;
}

#-------------------------------------------指針函數&多次輸入到一個指針數組中------------------------------#

#include <iostream>
#include <cstring> //#include <string>也可以

using namespace std;

char* getname(); //聲明一個指針函數,因為是要返回一個地址,所以要聲明指針函數

int main()
{
char* name;

name = getname(); //將指針函數返回的地址賦給name
cout<<name<<" at "<<(int*)name<<endl; //顯示獲取的name並顯示存儲的地址 在cout中的name只有char型指針才會打印字符串,其余類型的指針都會顯示地址
delete [] name; //釋放內存

name = getname(); //再次調用指針函數 註意在指針函數中出現了new,下面會有delete,所以new和delete還是成對出現的
cout<<name<<" at "<<(int*)name<<endl;
delete [] name;

cout<<name[0]<<"自己加的,確認一下name中是否存儲了上次從鍵盤輸入的名字"<<endl; //應該是不行的,因為name就是一個指針變量,不是數組啊

return 0;
}

char* getname()
{
char temp[80]; //新建一個可以存儲80個字符的char型數組
cout<<"Enter last name: ";
cin>>temp; //將從鍵盤輸入的名字臨時存儲於temp中

char* pn = new char [strlen(temp)+1]; //使用new關鍵字開創一個足以存儲strlen(temp)+1個字符的內存,並將地址賦給pn,加1是為了給最後的空字符\0留一個位置
strcpy(pn,temp); //將temp復制給pn

return pn; //返回存儲輸入名字的地址
}

最後編輯於 2019.02.18 22:46 家

研一寒假03_string定義字符串_指著(2)_指針&動態結構