1、數組指標聲明的時候不用初始化,聲明以後就指向數組的首地址了,以後不允許改變,所以,數組指標可以認為是一個常量,一旦賦值就不能改變
2、char數組
(1)列印char數組的名字即列印數組的內容
(2)對於字元數組,'\0'是結束標誌
字元 '\0' = 數組0 可以認為字元'\0'的ASCII碼就是0
要儲存5個字元,就要把字元數組長度聲明為6
(3)strcpy()和memset()
給一個字串數組賦值 strcpy(),自動為字串補 '\0'
在使用strcpy之前,要調用memset(str,0,sizeof(str));初始化一片記憶體
str -> 初始化記憶體的起始位置
0 -> 初始化的值 (初始化為0,清除垃圾數字)
sizeof(str) -> 初始化空間的大小
(4)strlen(str)
計算實際儲存的字元個數,不包括'\0'
(5)strcmp(str1,str2)
比較2個字串是否相等
實際比較的兩個字串的ASCII碼的大小,返回0則內容一樣
(6)字串的拆分 strtok(a,b);
a、被拆分的字串名字,當此處是NULL時,表示要拆分的不是新串
b、分隔字元號
此函數調用一次,拆分一次
當此函數返回NULL時,則表明拆分完畢
"Hello World"叫字串常量,儲存在data資料區裡,類型就是char*
其值是一個地址,指向資料區裡的一塊空間
資料區裡的空間儲存的內容就是"Hello World"
char line[50]; strcpy(line,"1:liucy:20:male"); char *p = strtok(line , ":"); //p指標指向的變數 cout << p << endl; while(p != NULL){ p = strtok ( NULL , ":" ); cout << p << endl; }
(7) strcpy(name,"1234"); //name是個變數,可以改變
strcpy(p,"1234"); //p是個指標,指向一個字串,是常量,不能改變
p = "1234"; //這樣是正確的
指標指向的是常量,不能通過指標改其值,若指向變數,則可以通過指標改變變數的值
(8)字串串連 strcat(sub,"world");
串連條件:sub字串數組的剩餘長度要大於串連的字串長度
char *p = "Hello";
strcat(p,""World); //error 指標指向一個常量,不能改變,所以指標後面不能添加東西
3、通過指標傳遞參數
通過傳遞地址。改變變數的值
#include <iostream> using namespace std; void fn (int *pa){ *pa = 2 * (*pa); //*pa是指標pa指向的變數的值,在此做的操作,會對變數造成永久的改變 } int main(){ int a = 100; fn(&a); //把a的地址傳個fn函數 cout << a << endl; return 0; }
4、課堂練習
字串 “1:huxinzhe:20:male”
要求:聲明一個結構
Person{
int id;
char name[50];
int age;
char gender[10];
}
拆分賦值 提示:atoi可以把字串轉換成int型
View Code
#include <iostream> #include <string.h> #include <stdlib.h> using namespace std; struct Person{ int id; char name[20]; int age; char gender[10]; }; int main(){ Person per; char line[50]; while(true){ cout << "enter a string>"; cin>>line; if(strcmp(line,"exit")==0) break; char *p = strtok(line , ":"); per.id = atoi(p); p = strtok(NULL , ":"); strcpy(per.name,p); p = strtok(NULL , ":"); per.age = atoi(p); p = strtok(NULL , ":"); strcpy(per.gender,p); cout <<"per.id = " <<per.id << endl; cout <<"per.name = " <<per.name << endl; cout <<"per.age = " <<per.age << endl; cout <<"per.gender = " <<per.gender << endl; } return 0; }
5、記憶體管理
堆(heap):動態記憶體申請與釋放
堆空間不能通過像( 資料區,棧)變數訪問空間,要使用指標儲存地址
(1)堆空間的管理 new / delete
new int
new Person
new 操作符傳回值是地址,用指標儲存
int *p = new int; //在堆空間中申請4個位元組
*p = 100; //賦值
delete p; //釋放空間
(2)動態申請空間,對記憶體的使用變的方便,能更好的控制對記憶體的佔用
動態記憶體的指標不能重複賦值,這樣會造成記憶體丟失
釋放空間後,還可以通過指標訪問原來的資料。
釋放空間後,還可以再次通過指標賦值,釋放的意思就是表示曾經申請的記憶體的標記位更改,別人可以使用
這樣會造成到期的指標更改重要資料,建議在釋放指標以後 ,把指標賦值為NULL ,確保資料安全
delete p ;
p = NULL :
(3)在申請空間的同時初始化
int *p = new int(123); 申請4個位元組大小,儲存數字“123”
(4)int *p = new int[10]; 一次在堆裡申請10個int,並且申請的記憶體是連續的。
*(p+1) , p[1] 都能取到下一個資料
此時的*p就是第一個元素的值
在釋放的時候 delete[] p; p = NULL; 確保釋放的是多個指標
(5)在堆空間裡申請結構
Person *p = new Person;
p->id = 1;
// (*p).id = 1;
6、 傳遞參數
最好傳地址,節省記憶體(因為不用進行入棧,出棧操作,直接用指標訪問資料)
在參數前加const,可避免在函數內部對資料進行非法修改
當一個數組做參數時,編譯器會自動把數組的首地址傳個函數
所以在函數內部對數組的更改,就是通過指標對數組中元素的永久性更改
7、數組,存資料個數不限,通過一個函數insert()存資料,disp()列印數組