?? ex11.cpp
字號:
// 第11章 字符和內存處理
// [例11.1]無結尾字符'\0'的數組輸出顯示的結果是不確定的
# include<stdio.h>
void main(void) // char c[]="abc";等價于char c[4] = {'a', 'b','c', '\0'};
{ char c[]="abc"; //相當于char c[4];c[0]= 'a'; c[1]= 'b'; c[2]= 'c'; c[3]= '\0';
c[3]='d'; printf("c->%p->%s,sizeof(c)=%d\n",c,c,sizeof(c));
} //輸出:c->0065FDF4->abcd8??,sizeof(c)=4
//[例11.2]字符串初始化指針和數組的差異
# include<stdio.h>
void main(void)
{ char* s="123456789"; printf("s->%p:%s,%s sizeof(s)=%d\n",s,s,s+4,sizeof(s));
char c[]="abcdefghi"; printf("c->%p:%s,%s sizeof(c)=%d\t",c,c,c+7,sizeof(c));
for(int k=0;k<9;k++) printf("%c,",s[k]);
printf("%d\n",s[9]);
} //程序運行輸出結果:
//s->00420FA0:123456789,56789 sizeof(s)=4
//c->0065FDE8:abcdefghi,hi sizeof(c)=10 1,2,3,4,5,6,7,8,9,0
/// [例11.3] 從屏幕讀取文本串到字符數組中
#include<stdio.h>
void main(void)
{ char a[12],b[6],*p=a; //定義兩個字符數組a,b。字符指針p,p等于a
printf("鍵入文本串\n");
scanf("%s %s",a,b); //讀入字符串時格式控制以空格分隔
printf("%s,%s\n",a,b);
scanf("%s ",p);
printf("%s \n",a);
}
//[例11.4]字符串初始化二維字符數組
#include <stdio.h>
void show(char*p) //輸出以p定位的其后5個字符的十進制數
{ int k=0; //不要求實參字符指針指向'\0'結尾的字符串
while( k<5) printf("%d,",p[k++]);
}
void main(void)
{ char a[][5]={"1","23"};
char b[2][5]={49,0,0,0,0,50,51,0,0,0};
show(a[0]); show(a[1]);printf("\n"); //輸出49,0,0,0,0,50,51,0,0,0,
show(b[0]); show(b[1]); //輸出49,0,0,0,0,50,51,0,0,0,
}
// [例11.5]二維數組初始化完整形式
# include<stdio.h>
extern void f(char s[3][5],int n);
void main(void)
{ char s[][5]={{' ',' ','*',' ',' '},
{' ','*',' ','*',' '}, {'*','*','*','*','*'}};
f(s,0);printf("\n");f(s,1);
}
/// [例11.6]二維數組初始化截斷形式
# include<stdio.h>
extern void f(char s[3][5],int n);
void main(void)
{ char b[][5]={{' ',' ','*'},
{' ','*',' ','*'}, {'*','*','*','*','*'}};
f(b,0);printf("\n");f(b,1);
}//設執行文件為a.exe
void f(char s[3][5],int n) //注意上面兩者初始化形式的差異!
{ for(int j=0;j<3;j++)
{ for(int k=0;k<5;k++) //內層循環為if~else語句
if(n==1) printf("%c",s[j][k]); // n==1輸出字符
else printf("%d,",s[j][k]); //否則輸出字符的ASCII碼的十進制數
if(n==1) printf("\n");
}
}
// [例11.7]字符串初始化字符指針數組和二維字符數組
# include<stdio.h>
void main(void)
{ char *pa[]={"a","bc","def","higk"};//字符串初始化字符指針數組
int n=sizeof(pa)/sizeof(pa[0]); int k;
for(k=0;k<n;k++) printf("%p->%s ",pa[k],pa[k]);
printf("\nsizeof(pa)=%d,sizeof(pa[0])=%d\n",sizeof(pa),sizeof(pa[0]));
char ca[][5]={"1","23","456","7890"};//字符串初始化二維字符數組
n=sizeof(ca)/sizeof(ca[0]);
printf("sizeof(ca)=%d,sizeof(ca[0])=%d\n",sizeof(ca),sizeof(ca[0]));
for( k=0;k<n;k++) printf("%p->%s ",ca[k],ca[k]);
}
//[例11.8] 字符串初始化局部二維字符數組與生存期
# include<stdio.h>
char* sa(int n) //返回char*型指針值的函數
{//static
char ca[][5]={"1","23","456","7890"};
return ca[n];
}
//[例11.9] 字符串初始化指針數組與生存期(多學時)
# include<stdio.h>
char* ga(int i) //字符指針數組的元素pa[i]是指針
{ char *pa[]={"a","bc","def","higk"}; //pa[i]指向字符串占住的全局數據區
return pa[i]; //數組pa本身是局部數組
} // ga將全局數據區的地址pa[i]輸送給主控程序
void main(void) { for(int k=0;k<4;k++) printf("%p->%s ",ga(k),ga(k)); }
//[例11.10]二維字符數組行地址初始化指針數組(多學時)
# include<stdio.h>
char* ca(int i) //返回指針值的函數,返回的內存空間的地址應是可操作的
{ char c[][5]={"a","bc","def","higk"}; //c[4][5]是局部數組
char* pa[]={c[0],c[1],c[2],c[3]}; //pa[i]指向局部數組的數據區
return pa[i]; //數組pa本身是局部數組
} // ca將局部數據區的地址pa[i]輸送給主控程序
void main(void)
{ for(int k=0;k<4;k++) printf("%p->%s ",ca(k),ca(k)); }
//[例11.11]返回char**指針值的函數(多學時)
# include<stdio.h>
char** ppn(char *pp[],int n){return pp+n;} //函數返回相對于入口指針的偏移
void main(void)
{ char *pa[4]={"a","bc","def","ghijk"};//字符串初始化字符指針數組
for(int k=0;k<4;k++)
printf("%s",*ppn(pa,k)); //輸出:abcdefghijk
}
//[例11.12] 模擬strlen函數
unsigned int strlen1(const char*s) /**函數的要點說明**/
{ unsigned int length=0; // length紀錄字符串的個數
while(*s!='\0') {s++;length++;} //長度length中不含'\0'
return length; //返回不含結尾符的字符串長度
} //字符數組若無結尾字符則結果是游移的
#include<string.h>//字符串處理函數的原型在頭文件string.h中
#include<stdio.h>
void main (void)
{ char c[ ]="ab\0d";
printf("strlen(c)=%d,sizeof(c)=%d,%s\n",strlen1(c),sizeof(c),c);
c[2]='c'; printf("strlen(c)=%d,%s\n",strlen(c),c);
c[4]='e'; printf("strlen(c)=%d,%s\n",strlen(c),c);
printf("strlen(ab\053d)=%d,%s\n",strlen("ab\053d"),"ab\053d");
} //輸出結果:
//[例11.13] 模擬strcpy函數算例
char* strcpy1(char *dst,const char*s) /**函數的要點說明**/
{ char * p=dst; //p定位目標串的當前位置
while((*p=*s) !='\0') //要求源串中包括結尾字符'\0'
{p++; s++;} //向后遍歷
*p='\0'; //目標串中最后添補結尾字符'\0'
return dst; //返回目標串入口的原先地址
} //目標實參必須提供足夠的內存空間
#include<string.h>
#include<stdio.h>
void main (void)
{ char b[]="while Hsiang river is flowing northward" ;
char * c=new char[sizeof(b)];
printf("%s\n",strcpy1(c,b)); // strcpy1 函數調用作為右值直接參入運算
delete [] c;
} //輸出結果:while Hsiang river is flowing northward
/////[例11.14] 模擬strcpy函數算例
#include<string.h>
#include<stdio.h>
char* strcat1(char *dst,const char*src) /**函數的要點說明**/
{ unsigned int i=0; //目標串和源串需存在終止符'\0'
while(dst[i]!='\0') i++; //搜尋到dst串的末尾'\0'處
while((dst[i]=*src)!='\0'){i++;src++;} //在dst末尾處開始追加源串直到源串的末尾'\0'
return dst; //返回目標串的入口地址dst
} /**實參數組的長度下限down=strlen(dst)+ strlen(src)+1**/
void main (void)
{ char c[32]="abcd"; //只讀字符串初始化字符數組c
char *p="-efg"; //字符串首地址初始化字符指針p
strcat1(c,p); p="-hijk" ; printf("%s\n",strcat(c,p));
} //輸出:abcd-efg-hijk
///[例11.15] strcmp函數 功能模擬算例
int strcmp1(const char*s1,const char*s2) /**函數的要點說明**/
{ while(*s1==*s2) //從頭到尾逐個字符按ASCII碼進行相同關系比較
{ //小寫字母比大寫字母的ASCII碼大。
if(*s1=='\0') return 0; //源串全等于目標串返回結果0。零差異返回
s1++; s2++; //雙指針同步向后搜尋
} //先判斷,如果*s1!=*s2則立即跳出循環
if(*s1>*s2) return 1; //源串第k+1個字符大于相應目標串返回正1
return -1; //源串小于目標串返回負1,前k個字符是一樣的
} //其中k滿足0<=k<=min(strlen(s1),strlen(s2))
#include<string.h>
#include<stdio.h>
void main (void)
{ char sa[]="abCd"; const char *sb="abcd"; char *sc="abcd";
if(strcmp(sc,sb)==0) printf("sc=sb--%s\n",sc); // 輸出:sc=sb--abcd
printf("strcmp(sa,sb)=%d\n",strcmp1(sa,sb)); // 輸出:strcmp(sa,sb)=-1
printf("strcmp(sb,sa)=%d\n",strcmp(sb,sa));// 輸出:strcmp(sb,sa)=1
}
////[例11.16] 排序法對多個字符串按字母次序排列
# include<stdio.h>
#include<string.h> //字符指針引用形參
inline void swap(char*& x,char*& y) {char* p=x;x=y;y=p;}
void SelectSort(char* a[], int n)
{ for(int i=0;i<n-1;i++)
{ ////進入內層循環前[]() int min=i; //設置最小元素下標初始值為i
for(int j=i+1;j<n;j++) //在區間中()尋找最小值對應的下標min
if(strcmp(a[j],a[min])<0) //條件成立時
min=j; //最小元素下標動態對應最小元素的位置
if(min!=i) //如果最小值對應的下標min在區間()中
swap(a[i],a[min]); //交換元素后[,]() } } void ExchangeSort(char* a[],int n) //指針數組形參a
{ for(int i=0;i<n-1;i++) //外循環n-1次,排序好s[0]<s[1]<...<s[n-2]
for(int j=i+1;j<n;j++) //循環將s[i]...s[n-1]中的最小值置于s[i]中
if(strcmp(a[i],a[j])>0) // 互換兩元素
{ char *p=a[i];a[i]=a[j];a[j]=p;}
}
void main(void)
{ char *ca[]={"For","Before","FOR","And","anyone"};
const int n=sizeof(ca)/sizeof(ca[0]); int k;
for( k=0;k<n;k++) printf("%p->%s ",ca[k],ca[k]);
typedef void (*VCI)(char*[],int);
VCI pfn[3]={SelectSort,ExchangeSort};
k=1; //k取值0、1輸出效果相同
(*pfn[k])(ca,n); printf("\n after Sort\n");
for( k=0;k<n;k++) printf("%p->%s ",ca[k],ca[k]);
}
/// [例11.17] 內存拷貝運算
#include<string.h>
#include<stdio.h>
void* memcpy1(void *dst,const void*src,size_t n)//memcpy功能模擬說明
{ char* pd=( char*)dst; //強制轉換void*型為 char*類型
char* ps=( char*)src; //以便進行確定的內存尋址訪問
unsigned int k=0; //定位當前位置的計數
while(k< n ) //先判斷然后做數據的輸送
{ *pd++=*ps++; k++;} //向高地址方向遍歷
return dst; //返回目標串的地址
}
void main (void)
{ long e[]={1,2,3}; //定義3個元素的long型數組e
long d[5]; //定義5個元素的long型數組d
memcpy1(d,e,sizeof(e)); //數組e[3]拷貝到數組d[5]的前三個元素
memcpy(d+3,e+1,sizeof(long[2])); //相當于d[3]=e[1],d[4]=e[2]
printf("d=[%d,%d,%d,%d,%d]\n",d[0],d[1],d[2],d[3],d[4]);
} //輸出: d=[1,2,3,2,3]
///[例11.18] a.cpp 簡單的void型無入口形參的main函數
# include <stdio.h>
void show(int argc,char* argv[]) //指針數組形參char* argv[]等價于char** argv
{ argc=0; //顯示指針數組指向的字符串的函數show
while(*argv) //循環要求指針數組中存在一個結束循環的0
printf("argv[%d]=%s\n",argc++,*argv++);
printf("argv[%d]=%d\n",argc,(char)*argv);
}
void main(void) /*程序運行輸出結果*/
{ /* argc=4 */
char* argv[]={"c:\\a.exe","a","bb",0}; /*argv[0]= c:\a.exe */
int argc=sizeof(argv)/sizeof(argv[0]); /*argv[1]=a */
printf("argc=%d\n",argc); /*argv[2]=bb */
show(argc,argv); /*argv[3]=0 */
}
//// [例11.19] m.cpp帶命令行參數的main函數
# include <stdio.h>
extern void show(int argc,char* argv[]);
void main(int argc, char* argv[])
{ printf("argc=%d\n",argc);
show( argc,argv);
}
///////// [例11.20] echo.cpp的執行文件echo.exe在根目錄C:\下
# include<stdio.h>
void main(int argc, char** argv)
{ for (register int k=1;k<argc;k++)
printf("%s%c",argv[k],(k<argc-1)?' ':'\n');
} //程序運行如下(不輸出執行文件的命令名):
//C:\>鍵入echo xxxx dddd( 得到輸出: xxxx dddd
/// [例11.21]a.cpp的執行文件a.exe在根目錄C:\下,輸出執行文件的命令名
# include <stdio.h>
void main(int n, char* s[]) { for(;n>0;n--,s++) printf("%s,",*s); }
//C:\>鍵入a xxxx dddd( 得到輸出:C:\a.exe,xxxx,dddd,
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -