日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

第三天2017/03/30(上午:二级指针的(输入)内存模型:(共三种模型))

發布時間:2025/3/21 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 第三天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(); }

兩個指針挖字符串模型

//作業題2:有一個字符串:形如“aaaa,bbbbb,ccccc,dddd”。 // 以逗號為分隔符,把aaaa\bbbbb\ccccc\dddd保存到一個二維字符數組中 int array2outarray(char* array,char outarray[10][30],int *count_) //自己寫 {strcat(array,",");int N = 0; //N表示返回的子串的個數if(array==NULL) //如果array是空的字符串{N = 0;return N;}int count = 0;int len = 0;char *p = array;char *h = p ; //始終指向“子字符串”的頭部while(*p!='\0'){p = strstr(h,","); //在字符串中找逗號if(p==NULL)break;len = p-h;strncpy(outarray[count],h,len); //count表示第幾個子字符串outarray[count][len] = '\0';len = 0;count++;p++;h = p;}*count_ = count;return 0;} int spitString(char* array,char ch /*分隔符*/,char buf[10][30],int *count) //掃地僧答案 {//兩個輔助指針變量“挖字符串”//1、p和ptemp初始化,都指向子串首地址char *p = array;strcat(p,",");char *ptemp = p;int p_ptemp = 0;int count_temp = 0;//2、執行strstr或者strchr,結果保存到p中//如果找到,那么p和ptemp正好形成一個差值p_ptemp//3、再次讓p和ptemp都達到檢索條件的開始位置//4、循環1.2.3,直到不符合while條件退出循環while(*p!='\0'){p = strchr(p,',');if(p==NULL)break;p_ptemp = p-ptemp;memcpy(buf[count_temp],ptemp,p_ptemp);buf[count_temp][p_ptemp] = '\0';p++;ptemp = p;count_temp++;p_ptemp = 0;}*count = count_temp;return 0; } int main() {//作業題:有一個字符串:形如“aaaa,bbbbb,ccccc,dddd”。// 以逗號,為分隔符,把aaaa\bbbbb\ccccc\dddd保存到一個二維字符數組中int count = 0;char array[] = "aaaa,bbbbb,ccccc,dddd,ee,,,";char buf[10][30];//spitString(array,',',buf,&count); //掃地僧寫array2outarray(array,buf,&count); //自己寫cout<<"打印二維數組"<<endl;for(int i=0;i<count;i++){cout<<*(buf+i)<<endl;}getchar(); }

總結

以上是生活随笔為你收集整理的第三天2017/03/30(上午:二级指针的(输入)内存模型:(共三种模型))的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。