版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
C语言程序设计指针第8章学习目标掌握指针的操作方法2了解指针的概念,掌握指针变量定义和初始化1掌握指针引用数组方法4掌握指针在字符串操作和字符数组中应用5掌握指针与函数的相关运用3了解指针数组和命令行操作68.1指针与指针变量计算机是以字节为单位对内存进行管理的,每个内存单元都有唯一的编号,根据编号可准确地找到该内存单元,内存单元的编号也叫作地址。对一个内存单元来说,内存单元的地址即为指针,内存单元中存放的数据就是该内存单元的内容。在C语言中,每种类型的数据(变量或数组元素)都占用一段连续的内存单元,该数据的地址或指针就是指该数据对应存储单元的首地址。【例8-1】读取变量首地址、所占字节数和变量值。程序代码:#include<stdio.h>voidmain(){
inta=1;doubleb=2;charc='A'; printf("a的首地址%p,a所占的字节数%d,a的内容%d\n",&a,sizeof(a),a); printf("b的首地址%p,b所占的字节数%d,b的内容%.1f\n",&b,sizeof(b),b); printf("c的首地址%p,c所占的字节数%d,c的内容%c\n",&c,sizeof(c),c);}运行结果:a的首地址0019FF2C,a所占的字节数4,a的内容1b的首地址0019FF24,b所占的字节数8,b的内容2.0c的首地址0019FF23,c所占的字节数1,c的内容A8.1指针与指针变量变量的访问方式计算机系统对变量的访问形式有两种:直接访问和间接访问。(1)直接访问变量名会被系统解析为地址,因此通过变量名或地址访问一个变量值的方式称为“直接访问”。例如,inta=15,直接对a变量进行初始化赋值。(2)间接访问“间接访问”方式就是把一个变量的地址放在一个特殊的变量中,利用这个特殊的变量进行访问该变量。例如,特殊变量p存放的内容是变量a的地址,利用变量p对变量a进行访问就是间接访问。通常称变量p指向变量a,变量a是变量p所指向的对象。在C语言中,用“指针”来表示一个变量指向另一个变量的指向关系,“指针”是专门存放地址的变量,称为指针变量。8.1指针与指针变量1.指针变量的定义指针变量是一种特殊的变量,它只能用来存放地址,而不能用来存放其他类型(整型、实型、字符型),指针变量需要专门加以定义。指针变量必须定义为“指针类型”,其定义的一般形式为:基类型*指针变量名其中,“基类型”是该指针变量所指向的变量的类型,不是指针变量自己的类型。下面是正确的定义形式,分别定义了基类型为整型、实型和字符型的指针变量p1、p2、p3:int*p1;//*为指针说明符float*p2;char*p3;有了以上定义,则指针变量p1只能存储int类型变量的地址,p2只能存储float类型变量的地址,p3只能存储char型变量的地址。8.1指针与指针变量(1)定义指针变量时,“*”是一个说明符,表示该变量的类型为指针型变量。(2)基类型是指针变量所指向的对象的数据类型。(3)指针变量存储的是指向变量的地址,地址的类型只能是int型或long型。而指针常量是指所引用的对象的地址不能改变的指针。(4)指针变量名与普通变量一样,使用合法的标识符为方便起见,在以后的讨论中,不再区分指针与指针变量,按习惯把指针变量简称为“指针”。【例8-2】指针变量的初始化和赋值。程序代码:#include<stdio.h>voidmain(){ inta=5,*p=&a; printf("a的地址:%p,p的值:%p\n",&a,p);printf("a的值:%d,*p的值:%d\n",a,*p);}指针变量的初始化和赋值将需要指向的变量的地址赋给相应的指针变量,要求二者的类型一致。例如,下面语句就实现了指针变量p指向变量a。inta,*p;//此句为定义:*号为指针说明符,说明p为指针变量*p=&a; //此处为赋值:*号为指针运算符,&为取地址符,取a的地址赋给指针变量p指针变量也可将定义说明与初始化赋值合二为一,可写成:inta=5;int*p=&a;或写成:inta=5,*p=&a;空指针NULL对全局指针变量与局部静态指针变量而言,在定义时若未被初始化,则编译系统自动初始化为空指针。8.1指针与指针变量指针变量的引用下面说明两个与指针操作有关的运算符:&和*。(1)&:取地址运算符,得到变量的地址。(2)*:指针运算符,或称指向运算符、间接访问运算符。可用运算符“*”引用指针变量。“*”运算符用于某个地址(如指针变量)之前,表示取*后地址中的内容。【例8-3】指针运算符和取地址符的应用示例。#include<stdio.h>voidmain(){ inta,*p=&a; a=12; *p=13; printf("%d,%d",*p,a);}【例8-4】用scanf()函数给变量a赋值并输出。#include<stdio.h>voidmain(){ inta,*p=&a; scanf("%d",&a); printf("a=%d\n",a); scanf("%d",&*p); printf("a=%d\n",*&a); scanf("%d",p); printf("a=%d\n",*p);}8.1指针与指针变量指针的赋值运算(2)相同类型的指针变量间的赋值此外,指针变量与一般的变量一样,存放在它们之中的值是可以改变的,也就是说可以改变它们的指向,例如:p2=pl;则pl与p2就会指向同一对象a,此时,*p2就等价于a,而不是b。因为只有相同类型的指针变量才能相互赋值,所以“p3=p1;”是非法的,因为p3是浮点型指针。指针的赋值运算(1)将变量地址值赋给指针变量,使指针指向该变量。设有如下定义:inta,b,*p1,*p2;float*p3;第1行定义了整型变量a、b及指针变量p1、p2。p1、p2还没有被赋值,因此不指向任何变量。下面的语句:a=12;b=18;p1=&a;p2=&b;第1行对a、b变量赋值,第2行、第3行分别将变量a、b的地址赋给指针变量p1、p2,使p1、p2分别指向变量a与b。这样,*p1等价于a,*p2等价于b。8.1指针与指针变量【例8-5】从键盘上输入两个整数到变量a和b,按由小到大输出。#include<stdio.h>voidmain(){inta,b,*pa=&a,*pb=&b,*p;scanf("%d%d",&a,&b);if(*pa>*pb){p=pa;pa=pb;pb=p;}printf("a=%d,b=%d\n",a,b);printf("min=%d,max=%d\n",*pa,*pb);}//方法二:通过指针间接访问变量,a和b的值发生了改变#include<stdio.h>voidmain(){ inta,b,*pa=&a,*pb=&b,p; scanf("%d%d",&a,&b); if(*pa>*pb) {p=*pa;*pa=*pb;*pb=p;} printf("a=%d,b=%d\n",a,b); printf("min=%d,max=%d\n",*pa,*pb);}8.1指针与指针变量指针的算术运算指针可以进行算术运算。一个指针可以加减一个整数n。【例8-6】指针的算术运算。程序代码:#include<stdio.h>voidmain(){ intn=2,*p1=&n; charm='A',*p2=&m; p1=p1+1; p1--; *p1++; p2=p2-1; p2++; (*p2)++; printf("n=%d,n=%d\n",n,*p1); printf("m=%c,m=%c\n",m,*p2);}(1)p=p+n:表示p向高地址方向移动n个存储单元块(一个单元块是指指针所指变量所占存储空间)。(2)p=p-n:表示p向低地址方向移动n个存储单元块。(3)p++、++p是把当前指针p向高地址移动一个存储单元。若p++作为操作数,则先引用p,再将p向高地址方向移动一个存储单元块,而++p是先移动指针后再引用p。p--、--p道理同上,是向低地址移动。(4)*p++中*和++两个运算符级别都是二级,要考虑结合性(自右向左),相当于*(p++),首先取*p的值,再执行指针的p=p+1。(5)(*p)++,相当于p指向变量的值加1。指针的关系运算指针可以进行关系运算。两个指针可以用关系表达式进行所有的关系运算。(1)指针进行关系运算之前,指针必须指向确定的变量或存储区域,即指针有初始值。另外,只有基类型相同的指针才能进行比较。(2)若p、q是两个基类型相同的指针变量,则p>q、p<q、p==q、p!=q等操作都是允许的。(3)假设p、q是指向同一数组的两个指针,执行p>q的关系运算,若成立,说明p所指元素在q所指元素之后,或者说q所指元素离数组的第1个元素更近些。8.1指针与指针变量指针不但可以指向基本类型变量,亦可以指向指针变量,这种指向指针型数据的指针变量称为指向指针的指针,或称多级指针。下面以二级指针(双重指针)为例来说明多级指针的定义与使用。二级指针的定义形式如下:基类型**指针变量;例如:intm=10,*p1,**p2p1=&m;p2=&p;其中,m的地址为2000,保存在指针变量p1中,p1指向a;p1的地址值为2100,保存在p2中,即双重指针p2指向指针变量p1,此时,要引用m的值,可用*p1,也可用**p2。二级指针与一级指针是两种不同类型的数据,尽管它们保存的都是地址,但不可以相互赋值。使用双重指针可以在建立复杂的数据结构时提供较大的灵活性。理论上还可以定义更多级的指针,如可以定义三级指针:char***p3;【例8-7】二级指针的使用。程序代码:#include<stdio.h>voidmain(){ int m=10,*p1,**p2; p1=&m; p2=&p1; printf("*p1=%d\n",*p1); printf("**p2=%d\n",**p2);}二级指针示意图8.2指针与函数【例8-8】编写一个交换变量值的函数,在主程序中调用,用指针做实参。#include<stdio.h>intswap(int*p1,int*p2){ intp; p=*p1; *p1=*p2; *p2=p;return0;}voidmain(){ inta,b; int*pa,*pb; scanf("%d%d",&a,&b); printf("交换前a=%d,b=%d\n",a,b); pa=&a; pb=&b; swap(pa,pb); printf("交换后a=%d,b=%d\n",a,b);}【例8-9】编写一个交换变量值的函数,在主程序中调用,用变量地址作为实参。#include<stdio.h>voidswap(int*p1,int*p2){intp;p=*p1;*p1=*p2;*p2=p;}intmain(){inta,b;scanf("%d%d",&a,&b);printf("交换前a=%d,b=%d\n",a,b);swap(&a,&b);printf("交换后a=%d,b=%d\n",a,b);return0;}指针作为函数参数函数形参为指针变量,用变量地址作为实参8.2指针与函数指针函数是一种函数,该函数的返回值是指针类型的数据。指针函数定义的一般形式为类型标识符*函数名(形参列表)例如:int*fun(inta,intb){函数体语句}函数fun是一个指针函数,要求返回值为一个int型指针,这就要求在函数体中有返回指针或地址的语句。例如:return(&变量名);return(指针变量);【例8-10】用指针函数求两个数的最小值,并输出。#include<stdio.h>intmain(){intm,n,*p;int*min1(int,int);//min1函数声明int*min2(int*,int*);//min2函数声明scanf("%d,%d",&m,&n);p=min1(m,n);//实参为变量值,返回值为指针printf("min1=%d\n",*p);p=min2(&m,&n);//实参为变量地址,返回值为指针printf("min2=%d\n",*p);return0;}int*min1(inta,intb){if(a<b)return(&a);//返回变量的地址elsereturn(&b);}int*min2(int*a,int*b){int*c;c=*a<*b?a:b;//将最小值的地址给指针creturn(c);//返回指针c的地址}指针函数8.2指针与函数指向函数的指针是一种指针,它的指向对象是一个函数。每个函数在内存中都有入口地址,函数名被系统解析为入口地址,函数的入口地址称为函数的指针。如果定义一个指针变量,其值等于该函数的入口地址,即该指针指向了这个函数。我们通过这个指针变量来调用该函数,这种指针变量称为指向函数的指针变量。指向函数的指针变量定义的一般形式为类型标识符(*指针变量名)();例如:int(*p)();float(*q)();定义的指向函数的指针变量,也像其他指针变量一样需要赋以地址才能引用。当将某个函数的入口地址赋给指向函数的指针变量后,就可用该指针变量来调用所指向的函数。函数名代表了函数的入口地址,我们只需将函数名赋给函数指针即可。例如,max(x,y)是一个求x和y中最大值的整型函数。p为指向返回值为整型的函数的指针,则下面的赋值语句:p=max;表示p指向max函数,即将max函数的入口地址赋给指针变量p。因为函数名max代表函数的入口地址,所以,在赋值时无须考虑函数参数。指向函数的指针8.2指针与函数若a是一个整型变量,则有以下两种方法实现函数调用:第一种,我们熟悉的函数名调用法,称为直接调用,如a=max(m,n);第二种,使用指针p调用函数,称为间接调用,如a=(*p)(m,n);二者是等价的。用指针调用函数的一般形式为(*指针变量)(实参表)【例8-11】编写程序,自定义max函数求一维数组的元素的最大值。在主调函数中用两种方法调用max函数:第1种方法,用“指针”调用;第2种方法,用“函数名”调用。程序代码:#include<stdio.h>intmax(inta[],intn){intk,s;s=a[0];for(k=0;k<n;k++)if(s<a[k])s=a[k];returns;}voidmain(){ints1,s2;inta[5]={1,2,3,4,5};int(*p)();//定义指向函数的指针pp=max;//函数名(函数入口地址)赋给指针s1=(*p)(a,5);//第1种方法:用“指针”调用max函数s2=max(a,5);//第2种方法:用“函数名”调用max函数printf("s1=%d\n",s1);printf("s2=%d\n",s2);}8.3指针与数组1.指向一维数组的指针变量定义一个一维数组后,系统为数组的所有元素分配固定的内存空间,数组名就代表了该数组所在内存空间的首地址,即数组名代表一个地址常量。一维数组每个元素的地址都可以通过数组名加下标值来取得。例如,定义一个一维数组a:inta[3];数组名a代表一维数组的起始地址。数组元素地址:a[0]、a[1]、a[2]的地址依次为a+0、a+1、a+2数组元素的值:a[0]、a[1]、a[2]的值依次为*(a+0)、*(a+1)、*(a+2)如果定义一个指针变量p,使p=a,则p指向数组a,该指针变量为指向一维数组的指针变量。指向数组的指针变量的定义与指向普通变量的指针变量的定义方法相同。例如:inta[3],*p;p=a;//或p=&a[0];指针变量也可以存放其他数组元素的地址,指向数组的其他元素。例如:p=&a[1];p=&a[2];执行该程序段之后,指针p先后指向a[1]、a[2]2.一维数组元素的引用方法引用一个数组元素的方法有两类:一是下标法,二是指针法。(1)下标法下标法即指出数组名和下标值,系统会找到该元素。前面介绍数组时都是采用的这种方法。(2)指针法指针法也称地址法。通过给出的数组元素地址访问某一元素。例如,指针变量p指向数组a的首地址,引用数组a的第i个元素有四种表示法:数组起始地址+偏移量:*(a+i)指针+偏移量:*(p+i)指针遍历数组:*p指针替代数组名:p[i]8.3指针与数组【例8-12】使用5种方法输出整型数组a的各个元素。#include<stdio.h>voidmain(){inta[3]={1,2,3},i,*p=a;for(i=0;i<3;i++)printf("%d\t",a[i]);//下标法printf("\n");for(i=0;i<3;i++)printf("%d\t",*(a+i));//*(a+i)法printf("\n");for(i=0;i<3;i++)printf("%d\t",*(p+i));//*(p+i)法printf("\n");for(p=a;p<a+3;p++)printf("%d\t",*p);//*p法printf("\n");p=a;//将指针p重新指向a数组首地址for(i=0;i<3;i++)printf("%d\t",p[i]);printf("\n");}【例8-13】编写程序用指针法完成:从键盘上输入3个整数到数组a中,然后输出。程序代码:#include<stdio.h>voidmain(){inta[3],i,*p;p=a;//p指向a的首地址for(i=0;i<3;i++)scanf("%d",p++);//用指针p访问数组,并逐个赋值p=a;//上条执行后,p指针已经指向a数组之外,需重新归位for(i=0;i<3;i++)printf("%d\t",*(p++));//指针逐个指向数组元素并输出}8.3指针与数组1.二维数组的地址二维数组可以看作一个特殊的“一维数组”,此“一维数组”的每一个元素又是一个一维数组。例如,有一个二维数组定义如下:inta[2][3];数组a可被看作一个一维数组,它有两个元素:a[0]、a[1]。这两个元素都是长度为3的一维数组,数组元素a[i]的地址可以表示为a+i。a[i]又是一个一维数组,a[i]是此一维数组的数组名,它有3个元素:a[i][0]、a[i][1]、a[i][2]。2.二维数组元素的引用方法二维数组元素的引用方法与一维数组元素的引用方法有相似之处,因此也可以利用指针法来引用二维数组元素。二维数组元素a[i][j]的引用可以表示为*(a[i]+j),进而可以表示为*(*(a+i)+j)。【例8-14】用指针表示法输出二维数组的各元素。#include<stdio.h>intmain(){staticinta[2][3]={{1,2,3},{4,5,6}};intj,k,*p;for(j=0;j<2;j++){for(k=0;k<3;k++)printf("%d\t",*(a[j]+k));putchar('\n');}putchar('\n');for(j=0;j<2;j++){for(k=0;k<3;k++)printf("%d\t",*(*(a+j)+k));putchar('\n');}putchar('\n');p=a[0];for(j=0;j<2;j++){for(k=0;k<3;k++)printf("%d\t",*(p++));putchar('\n');}return0;}二维数组元素的引用方法,以m行n列的二维数组a的第i行j列元素为例:8.3
指针与数组下标法:a[i][j]指针法:*(*(a+i)+j)或*(&a[0][0]+n*i+j)行数组下标法:*(a[i]+j)列数组下标法:(*(a+i))[j]对于二维数组a,应注意以下几点:(1)二维数组名、数组首地址是常量指针。(2)a+i、&a[i]指向第i行(第i行首地址),是二级指针。(3)a[i]、*(a+i)、&a[i][0]指向第i行、第0列,是一级指针,其地址与a+i、&a[i]相同,注意不要认为*(a+i)是a+i指向的对象,因为在二维数组中,a+i指向行,而不指向具体单元。(4)a[i]+j和*(a+i)+j表示元素a[i][j]的地址。(5)*(a[i]+j)和*(*(a+i)+j)表示元素a[i][j]。8.3指针与数组指向二维数组的指针变量有两种情况:(1)直接指向数组元素的指针变量这种变量的定义与普通指针变量的定义相同,其类型与数组元素类型相同。【例8-15】用指针变量输入/输出二维数组中各个元素的值。程序代码:#include<stdio.h>voidmain(){inti,j,*p,a[2][3];p=&a[0][0];for(i=0;i<2;i++)for(j=0;j<3;j++)scanf("%d",p+i*3+j);for(i=0;i<2;i++){for(j=0;j<3;j++)printf("%d",*(p+i*3+j));printf("\n");}}(2)行指针变量指向一维数组(二维数组的一行)的指针,称为行指针。其定义的一般形式如下:类型标识符(*指针变量名)[N];其中“*”表示其后面的变量名为指针类型,N为元素个数,“类型标识符”表示一维数组元素的类型。在定义中“*指针变量名”作为说明部分,必须用括号标注。在定义和使用指向一维数组的指针变量p时,需要注意以下几点:(1)在定义行指针时,“(*指针变量名)”中的括号不能省略。(2)在定义行指针时,N必须是整型常量表达式,此时定义的行指针可以指向相同类型的具有N个列元素的二维数组中的一行。(3)由于p是行指针,因此p+i、p++或p--均表示指针移动的单位为行。(4)p只能指向二维数组中的一行,而不能指向行中的某个元素。例如:inta[2][4],(*q)[4]=a;其中,q是指向由4个元素组成的一维数组的行指针变量。表达式*q是一个含有4个元素的一维数组,它指向二维数组的第0行。可见,*q代表一维数组的首地址,*q+j是一维数组的第j个元素地址,*(*q+j)是一维数组的第j个元素。由此可推出数组元素a[i][j]的地址表示形式为*(q+i)+j,数组元素a[i][j]的表示形式为*(*(q+i)+j)。8.3指针与数组【例8-16】用行指针实现求二维数组中最大元素的值。程序代码:#include<stdio.h>voidmain(){intmax(int(*p)[3],intn);//函数的声明inta[2][3]={1,3,5,7,9,11};printf("maxis%d\n",max(a,2));}intmax(int(*p)[3],intn)//形参指针为行指针{intmax,i,j;max=*(*(p+0)+0);for(i=0;i<n;i++)for(j=0;j<3;j++)if(*(*(p+i)+j)>max)max=*(*(p+i)+j);returnmax;}运行结果:maxis118.4指针与字符串2.用字符指针变量指向字符串C语言对字符串是按字符数组处理的,在内存中开辟一个字符数组存放字符串,其首地址可保存在字符指针变量中。例如:char*c="studyhard"在这里,字符指针变量c存放的是字符串的首地址,而不是字符串的内容,用字符指针变量指向字符串。字符串的指针表示法1.用字符数组存放字符串例如:charc[]="studyhard";字符数组是由若干个数组元素组成的,在内存中占有一片连续的空间。字符数组用于存放字符或字符串,字符数组中的一个元素存放字符串中的一个字符,用字符数组存放字符串。8.4指针与字符串【例8-17】将一已知字符串从第n个字符开始的剩余字符复制到另一字符数组中。程序代码:#include<string.h>#include<stdio.h>voidmain(){intn;chara[]="computer";charb[10],*p,*q;p=a;q=b;scanf("%d",&n);if(strlen(a)>=n)p+=n-1;//指针指向要复制的第一个字符for(;*p!='\0';p++,q++)*q=*p;*q='\0';//字符串以'\0'结尾printf("Stringa:%s\n",a);printf("Stringb:%s\n",b);}虽然用字符指针变量和字符数组都能实现字符串的存储和处理,但二者是有区别的,不能混为一谈。(1)存储内容不同。字符指针变量中存储的是字符串的首地址,而字符数组中存储的是字符串本身(数组的每个元素存放字符串的一个字符)。(2)赋值方式不同。对于字符指针变量,可采用下面的赋值语句赋值。char*c;c="studyhard";对于字符数组,虽然可以在定义时初始化(如:charc[]="studyhard"),但不能用赋值语句对字符数组整体赋值。下面的用法是非法的:charc[11];c="studyhard";字符数组赋值可用字符串拷贝strcpy()函数。例如:charc[11];strcpy(c,"studyhard");(3)指针变量的值是可以改变的,字符指针变量也不例外,但数组名代表数组的起始地址,是一个常量,常量是不能被改变的。8.4指针与字符串字符串数组是指数组中的每个元素都是一个用于存放字符串的数组。字符串数组可以用一个二维字符数组来存储。例如:chara[3][5];该数组的第一个下标是字符串的个数,第二个下标是字符串的最大长度(实际最多4个字符,\0占1个位置)。可以对字符串数组赋初值。例如:chara[3][5]={"How","are","you!"}8.5
指针数组与命令行参数指针数组指针数组是指针变量的集合。它的每一个元素都是指针变量,且都具有相同的存储类别和指向相同的数据类型。指针数组定义的一般形式如下:类型标识符*数组名[数组元素个数];例如:int
*p[5]在定义中,“数组名[数组元素个数]”先组成一个说明部分,表示一个一维数组及其元素的个数,“类型标识符*”则说明数组中每个元素都是指针数据类型。一般情况下,运用指针的目的是操作目标变量,使得对目标变量的操作变得灵活并能提高运行效率。比如,使用指针数组处理多个字符串比使用字符数组更为方便灵活。例如:char
*p[3];定义了一个具有三个元素p[0]、p[1]、p[2]的指针数组。每个元素都可以指向一个字符数组或字符串。若利用数组初始化,则,char
*p[3]={"How","are","you!"};指针数组元素p[0]指向字符串“How”,p[1]指向“are”,p[2]指向“you!”。8.5指针数组与命令行参数【例8-18】有若干本书,将其书名按字典顺序排序。程序代码:#include<stdio.h>#include<string.h>voidmain(){char*bname[]={"ProgramminginANSIC","BASIC","VisualC++6.0Programming","TRUBOC2.0"};inti,m;voidsort(char*name[],int);m=sizeof(bname)/sizeof(char*);//字符串个数sort(bname,m);//排序,改变指针的连接关系printf("\n");for(i=0;i<m;i++)//输出排序结果printf("%8s",bname[i]);}voidsort(char*name[],intn)//选择排序{char*t;inti,j,k;//k记录每趟最小值下标for(i=0;i<n-1;i++){k=i;for(j=i+1;j<n;j++)if(strcmp(name[k],name[j])>0)k=j;//第j个元素更小if(k!=i)//最小元素是该趟的第一个元素,不需交换{t=name[i];name[i]=name[k];name[k]=t;}}}关于字符数组与指针变量,有以下两点需要注意:(1)字符数组中每个元素可存放一个字符,而字符指针变量存放字符串首地址,而不是整个字符串。(2)字符数组与普通数组一样,不能对其进行整体赋值,只能给各个元素赋值,而字符指针变量可以直接用字符串常量赋值。8.5指针数组与命令行参数“命令行”是在操作系统状态下输入程序或命令使其运行,输入的命令及命令所需参数称为“命令行参数”main函数是可以有参数的,C语言程序通过main函数的参数获取命令行参数信息。其一般形式为:[返回类型]main(intargc,char*argv[]){…}main函数的两个形参常用argc、argv。argc的值是命令行中参数的个数;argv是一个字符指针数组,这个数组里共有argc+1个字符指针变量,其中前argc个指针变量分别存储命令行参数的各字符串首地址,最后一个是空指针,表示数组结束。可以使用系统自动给定的参数argc和argv的初值编写程序,对“命令行”中的各个字符串进行操作。main函数所需的实参与形参的传递方式与一般C语言函数的参数传递有所不同,其实参是在命令行中与程序名一起输入的,程序名和各个实参之间用空格分隔,其格式为:执行程序名
参数1参数2…参数n形参argc为命令行中参数的个数(包括执行程序名),其值大于或等于1。形参argv是一个指针数组,其元素依次指向命令行中以空格分开的各字符串。8.5指针数组与命令行参数【例8-19】分析下列程序,指出其执行结果,该程序命名为example.c,经编译、链接后生成的可执行程序为example.exe。程序代码:#include<stdio.h>voidmain(intargc,char*argv[]){inti=0;printf("argc=%d\n",argc);while(argc>=1){printf("\nparameter%d:%s",i,*argv);i++;argc--;argv++;}}运行结果:命令行状态输入:exampleTurbo_cC++Vc输出:argc=4parameter0:exampleparameter1:Turbo_cparameter2:C++parameter3:Vc8.5指针数组与命令行参数#include<stdio.h>#include<string.h>voidfun(chars1[],chars2[]);intmain(intargc,char*argv[]){char*p,*q;p=argv[1];q=argv[2];fun(p,q);return0;}voidfun(chars1[],chars2[]){intn;charcolor[7][10]={"red","orange","yellow","green","cyan","blue","black"};for(n=0;n<7;n++)if(strcmp(color[n],s1)==0)strcpy(color[n],s2);for(n=0;n<7;n++)printf("%s\n",color[n]);}【例8-20】在字符数组color中存放了7个字符串:“red”“orange”“yellow”“green”“cyan”“blue”“black”。使用命令行参数“replaceblackpurple”,用purple替换数组color中的black。8.6程序举例#include<stdio.h>voidprintBinary(unsignedintn)//打印二进制表示{if(n>1)printBinary(n/2);printf("%d",n%2);}voidprintOctal(unsignedintn)//打印八进制表示{if(n>7)printOctal(n/8);printf("%d",n%8);}voidprintHexadecimal(unsignedintn)//打印十六进制表示{constcharhexDigits[]="0123456789ABCDEF";if(n>15)printHexadecimal(n/16);printf("%c",hexDigits[n%16]);}intmain(){unsignedintdecimalNumber;printf("请输入一个十进制正整数:");scanf("%u",&decimalNumber);printf("二进制表示:");printBinary(decimalNumber);printf("\n八进制表示:");printOctal(decimalNumber);printf("\n十六进制表示:");printHexadecimal(decimalNumber);printf("\n");return0;}运行结果:请输入一个十进制正整数:123二进制表示:1111011八进制表示:173十六进制表示:7B【例8-21】输入一个十进制正整数,将其转换成二进制、八进制、十六进制数输出。8.6程序举例【例8-22】用快速排序法对数组arr[6]={10,7,8,9,1,5}按由大到小的顺序排列并输出,要求用指针。#include<stdio.h>voidswap(int*a,int*b){inttemp=*a;*a=*b;*b=temp;}intpartition(int*arr,intlow,inthigh){intpivot=arr[high];inti=(low-1),j;for(j=low;j<=high-1;j++){if(arr[j]>pivot){i++;//增加iswap(&arr[i],&arr[j]);}}swap(&arr[i+1],&arr[high]);return(i+1);}voidquickSort(int*arr,intlow,inthigh){if(low<high){intpi=partition(arr,low,high);quickSort(arr,low,pi-1);quickSort(arr,pi+1,high);}}voidprintArray(int*arr,intsize){inti;for(i=0;i<size;i++)printf("%d",arr[i]);printf("\n");}intmain(){intarr
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年嵩山少林武术职业学院单招职业适应性测试题库及完整答案详解1套
- 2026年甘肃省陇南地区单招职业适应性测试题库及参考答案详解一套
- 2026年河北省石家庄市单招职业倾向性测试题库及答案详解一套
- 2026年长沙电力职业技术学院单招职业适应性考试题库及完整答案详解1套
- 2026年岳阳现代服务职业学院单招职业技能考试题库及参考答案详解1套
- 2026年江苏商贸职业学院单招综合素质考试题库及完整答案详解1套
- 2026年湖南都市职业学院单招职业适应性考试题库含答案详解
- 2026年嵩山少林武术职业学院单招职业技能测试题库及完整答案详解1套
- 2026年闽北职业技术学院单招职业适应性测试题库附答案详解
- 2026年宁波幼儿师范高等专科学校单招职业倾向性测试题库及答案详解一套
- 2025秋人教版(新教材)初中美术八年级上册知识点及期末测试卷及答案
- 2026年保安员考试题库500道附完整答案(历年真题)
- 2025至2030中国司法鉴定行业发展研究与产业战略规划分析评估报告
- (2025年)危重病人的观察与护理试题及答案
- 膝关节韧带损伤康复课件
- 个人契约协议书范本
- 医药区域经理述职报告
- 建筑施工项目职业病危害防治措施方案
- 船员上船前安全培训课件
- 袖阀注浆管施工方案
- 市政工程桩基检测技术操作规程
评论
0/150
提交评论