第三天2017/03/30(上午:二级指针的(输入)内存模型:(共三种模型))
生活随笔
收集整理的這篇文章主要介紹了
第三天2017/03/30(上午:二级指针的(输入)内存模型:(共三种模型))
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
二級(jí)指針
char a[10][10]; char (*a)[10];
char *a[10]; char **a;
char **a; char **a;
字符數(shù)組的操作易犯錯(cuò)誤:
1.字符數(shù)組在使用前是否分配空間
2.字符數(shù)組能否返回地址
3.定義char* p;臨時(shí)變量p,保存strstr等函數(shù)返回的地址。
【注】我們只有在使用指針?biāo)赶虻膬?nèi)存空間的時(shí)候,我們才去關(guān)心“指針的類型”。
二級(jí)指針作“輸入”時(shí),有下面三種內(nèi)存模型
//內(nèi)存模式一:函數(shù)原型下面4個(gè)(哪個(gè)正確,哪個(gè)錯(cuò)誤?) void print_s1(char **p, int n) //正確 //void print_s1(char *p[4],int n) //正確:形參和實(shí)參格式一樣 //void print_s1(char (*p)[30],int n) //錯(cuò)誤:類型不一致,編譯失敗 //void print_s1(char p[4][30],int n) //錯(cuò)誤:類型不一致,編譯失敗 {for(int i = 0;i<n;i++){cout<<*(p+i)<<endl; //等價(jià)于 cout<<p[i]<<endl; } }void sort_s1(char **p, int n) //正確 //void sort_s1(char *p[4],int n) //正確 //void sort_s1(char (*p)[30],int n) //錯(cuò)誤 //void sort_s1(char p[4][30],int n) //錯(cuò)誤 {char *temp;for(int i = 0;i<n;i++)for(int j = i+1;j<n;j++){if(strcmp(p[i],p[j])<0){//交換的是指向字符串首地址的指針temp = p[i]; p[i] = p[j]; p[j] = temp;}} }//內(nèi)存模式二:函數(shù)原型下面4個(gè)(哪個(gè)正確,哪個(gè)錯(cuò)誤?) //void print_s2(char **p, int n) //錯(cuò)誤,類型不一致,編譯失敗 //void print_s2(char *p[4],int n) //錯(cuò)誤,類型不一致,編譯失敗 //void print_s1(char (*p)[30],int n) //正確,char (*p)[4]相當(dāng)于char p[][4] void print_s2(char p[][30],int n) //正確:形參和實(shí)參格式一樣 {for(int i = 0;i<n;i++){cout<<*(p+i)<<endl; //等價(jià)于 cout<<p[i]<<endl; } }//void sort_s2(char **p, int n) //錯(cuò)誤 //void sort_s2(char *p[30],int n) //錯(cuò)誤 void sort_s2(char (*p)[30],int n) //正確 //void sort_s2(char p[][30],int n) //正確 {char temp[100]; //char *temp; //報(bào)錯(cuò),因?yàn)闆]有分配內(nèi)存就用strcpy往temp中復(fù)制元素,肯定崩潰for(int i = 0;i<n;i++)for(int j = i+1;j<n;j++){if(strcmp(p[i],p[j])<0){//此處不是(交換的是指向字符串首地址的指針),而是用函數(shù)strcpy進(jìn)行復(fù)制strcpy(temp,p[i]);strcpy(p[i],p[j]);strcpy(p[j],temp); }} }//內(nèi)存模式三:函數(shù)原型下面4個(gè)(哪個(gè)正確,哪個(gè)錯(cuò)誤?)==>類似于內(nèi)存模式 //void print_s3(char **p, int n) //正確 void print_s3(char *p[4],int n) //正確! //void print_s3(char (*p)[30],int n) //錯(cuò)誤 //void print_s3(char p[4][100],int n) //錯(cuò)誤:類型不一致,編譯失敗 {for(int i = 0;i<n;i++){cout<<*(p+i)<<endl; //等價(jià)于 cout<<p[i]<<endl; } }void sort_s3(char **p, int n) //正確 //void sort_s3(char *p[4],int n) //正確 //void sort_s1(char (*p)[30],int n) //錯(cuò)誤 //void sort_s3(char p[4][100],int n) //錯(cuò)誤 {char *temp;for(int i = 0;i<n;i++)for(int j = i+1;j<n;j++){if(strcmp(p[i],p[j])<0){//交換的是指向字符串首地址的指針temp = p[i]; p[i] = p[j]; p[j] = temp;}} } int main() { //內(nèi)存模式一:char *p1[4] = {"AAAAAA","CCCC","BBBB","DDDD"};//p1[3][3] = 'F'; //崩潰,因?yàn)閜[i]指針指向的是字符串常量(例如“AAAAA”),該字符串常量“AAAAA”(存放在常量區(qū))不能被修改cout<<"排序之前"<<endl;print_s1(p1,4);cout<<"排序之后"<<endl;sort_s1(p1,4);print_s1(p1,4);cout<<endl;//內(nèi)存模式二:char p2[4][30] = {"AAAAAA","CCCC","BBBB","DDDD"};p2[3][3] = 'F'; //正確,p[i]="AAAAA"(是靜態(tài)分配字符數(shù)組p[30])在此處相當(dāng)于給字符數(shù)組初始化,“AAAAA”存放在在棧中,可以被修改cout<<"排序之前"<<endl;print_s2(p2,4);cout<<"排序之后"<<endl;sort_s2(p2,4);print_s2(p2,4);cout<<endl;//內(nèi)存模式三:char **p3 = (char**)malloc(10*sizeof(char*));if(p3==NULL) //如果內(nèi)存分配失敗return 0;for(int i = 0;i<10;i++){*(p3+i) = (char*)malloc(30*sizeof(char));//p3[i] = (char*)malloc(30*sizeof(char));if(p3[i]==NULL) //如果內(nèi)存分配失敗return 0;sprintf(p3[i],"String%d",i);}p3[3][3] = 'F';//正確,p[i](是動(dòng)態(tài)分配的字符數(shù)組p[30]),在堆中,可以被修改cout<<"排序之前"<<endl;print_s3(p3,4);cout<<"排序之后"<<endl;sort_s3(p3,4);print_s3(p3,4);//使用完malloc分配的內(nèi)存,記得釋放,防止內(nèi)存泄漏for(int i=0;i<10;i++){free(p3[i]);p3[i] = NULL; //防止野指針}free(p3);p3 = NULL; //防止野指針getchar(); }【總結(jié)——二級(jí)指針的解決問題方案】
(1)先判斷:是輸入?輸出?
(2)若是輸入?
_則:根據(jù)具體情況進(jìn)行套用是三種模型中的哪一種模型!
作業(yè)題:
/* 作業(yè)題1:key~value查找指針數(shù)組中的字符串是否有key?如果有,把key~value輸出來(去掉空格) */ int strlen_trimSpace2(char *p,char *q) {//兩頭堵模型:求出除去前后空格的字符串的長度int count = 0;int i = 0,j = 0;j = strlen(p)-1; //記得 -1(減1)while(isspace(p[i]) && p[i]!='\0') //從前往后{ //isspace(c)檢查參數(shù)c是否為空格字符i++;}while(isspace(p[j]) && j>0) //從后往前{j--;}count = j-i+1;memcpy(q,p+i,count);q[count] = '\0';cout<<q<<endl; //為了不修改輸入的p字符數(shù)組,定義q作為接受數(shù)組return 0; }int key_value(char* input/*key*/,char **array,char* output/*找到的結(jié)果字符串*/,int *outstrLen) {int i = 0;char* p ;//保存查找到的地址if(input==NULL||output==NULL /*||&outstrLen==NULL*/){cout<<"input、output有一個(gè)為NULL"<<endl;return -1; //返回-1表示出現(xiàn)bug}//在array中查找子串inputfor(i=0;array[i]!=NULL;i++){p = strstr(array[i],input);if(p!=NULL) //如果查找到break;//查找成功(此時(shí)查找到的字符串是array[i])就跳出for循環(huán)}if(p==NULL) //如果沒查找到{//cout<<"在array[i]中查找input失敗"<<endl;return -2; //返回-2表示沒查找到}p = p + strlen(input); //跳過查找到的input字符//查找 = 號(hào)p = strstr(p,"=");p++; //跳過 = 號(hào)char temp[100];//兩頭堵:去掉字符串前后的空格strlen_trimSpace2(p,temp);strcat(input,"=");strcat(input,temp);strcpy(output,input);*outstrLen = strlen(output)+1;return 0; //返回0表示查找到 } int main() { /* 作業(yè)題:key~value查找指針數(shù)組中的字符串是否有key?如果有,把key~value輸出來(去掉空格) */char *array[5] = {"key1 = AAAA ","key2 = BBBBBBBB","key3 =CC","key4 = DDD ","key5 = EE "};char input[100] = "key111" ;char output[100];int outstrLen = 0;int ret = 0; ret = key_value(input,array,output,&outstrLen);if(ret==-2){//返回-2表示沒查找到cout<<"array中沒有input,查找失敗"<<endl;getchar();return 0;}else if(ret == -1){cout<<"程序錯(cuò)誤"<<endl;getchar();return 0;}else{cout<<" 找到字符串 :"<<output<<endl;cout<<"找到字符串的長度 : "<<outstrLen<<endl;}getchar(); }兩個(gè)指針挖字符串模型
總結(jié)
以上是生活随笔為你收集整理的第三天2017/03/30(上午:二级指针的(输入)内存模型:(共三种模型))的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第三天2017/03/30(下午:二级指
- 下一篇: 第四天2017/03/31(上午:指针、