📄 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 + -