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