⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 10.txt

📁 多数情况下
💻 TXT
📖 第 1 页 / 共 4 页
字号:
pa=pa+2;   /*pa指向a[2],即pa的值为&pa[2]*/
指针变量的加减运算只能对数组指针变量进行,对指向其它类型变量的指针变量作加减运算是毫无意义的。
3)	两个指针变量之间的运算:只有指向同一数组的两个指针变量之间才能进行运算,否则运算毫无意义。
①	两指针变量相减:两指针变量相减所得之差是两个指针所指数组元素之间相差的元素个数。实际上是两个指针值(地址)相减之差再除以该数组元素的长度(字节数)。例如pf1和pf2是指向同一浮点数组的两个指针变量,设pf1的值为2010H,pf2的值为2000H,而浮点数组每个元素占4个字节,所以pf1-pf2的结果为(2000H-2010H)/4=4,表示pf1和 pf2之间相差4个元素。两个指针变量不能进行加法运算。 例如,pf1+pf2是什么意思呢?毫无实际意义。
②	两指针变量进行关系运算:指向同一数组的两指针变量进行关系运算可表示它们所指数组元素之间的关系。
例如:
pf1==pf2表示pf1和pf2指向同一数组元素;
pf1>pf2表示pf1处于高地址位置;
pf1<pf2表示pf2处于低地址位置。
指针变量还可以与0比较。
设p为指针变量,则p==0表明p是空指针,它不指向任何变量;
p!=0表示p不是空指针。
空指针是由对指针变量赋予0值而得到的。
例如:
#define NULL 0
int *p=NULL;
对指针变量赋0值和不赋值是不同的。指针变量未赋值时,可以是任意值,是不能使用的。否则将造成意外错误。而指针变量赋0值后,则可以使用,只是它不指向具体的变量而已。
【例10.7】
main(){
  int a=10,b=20,s,t,*pa,*pb; /*说明pa,pb为整型指针变量*/
  pa=&a;                     /*给指针变量pa赋值,pa指向变量a*/
  pb=&b;                     /*给指针变量pb赋值,pb指向变量b*/
  s=*pa+*pb;                 /*求a+b之和,(*pa就是a,*pb就是b)*/
  t=*pa**pb;                 /*本行是求a*b之积*/
  printf("a=%d\nb=%d\na+b=%d\na*b=%d\n",a,b,a+b,a*b);
  printf("s=%d\nt=%d\n",s,t);
}
 
【例10.8】
main(){
  int a,b,c,*pmax,*pmin;             /*pmax,pmin为整型指针变量*/
  printf("input three numbers:\n");  /*输入提示*/
  scanf("%d%d%d",&a,&b,&c);         /*输入三个数字*/
  if(a>b){                          /*如果第一个数字大于第二个数字...*/
    pmax=&a;                        /*指针变量赋值*/
    pmin=&b;}                       /*指针变量赋值*/
  else{
    pmax=&b;                        /*指针变量赋值*/
    pmin=&a;}                       /*指针变量赋值*/
  if(c>*pmax) pmax=&c;              /*判断并赋值*/
  if(c<*pmin) pmin=&c;              /*判断并赋值*/
    printf("max=%d\nmin=%d\n",*pmax,*pmin); /*输出结果*/
}
 
10.3	数组指针和指向数组的指针变量
一个变量有一个地址,一个数组包含若干元素,每个数组元素都在内存中占用存储单元,它们都有相应的地址。所谓数组的指针是指数组的起始地址,数组元素的指针是数组元素的地址。
10.3.1	指向数组元素的指针
一个数组是由连续的一块内存单元组成的。数组名就是这块连续内存单元的首地址。一个数组也是由各个数组元素(下标变量)组成的。每个数组元素按其类型不同占有几个连续的内存单元。一个数组元素的首地址也是指它所占有的几个内存单元的首地址。
定义一个指向数组元素的指针变量的方法,与以前介绍的指针变量相同。
例如:
    int a[10];   /*定义a为包含10个整型数据的数组*/
int *p;      /*定义p为指向整型变量的指针*/
应当注意,因为数组为int型,所以指针变量也应为指向int型的指针变量。下面是对指针变量赋值:
p=&a[0];
把a[0]元素的地址赋给指针变量p。也就是说,p指向a数组的第0号元素。
 
C语言规定,数组名代表数组的首地址,也就是第0号元素的地址。因此,下面两个语句等价:
p=&a[0];
p=a;
在定义指针变量时可以赋给初值:
int *p=&a[0];
它等效于:
int *p; 
p=&a[0];
当然定义时也可以写成:
    int *p=a;
从图中我们可以看出有以下关系:
    p,a,&a[0]均指向同一单元,它们是数组a的首地址,也是0 号元素a[0]的首地址。应该说明的是p是变量,而a,&a[0]都是常量。在编程时应予以注意。
数组指针变量说明的一般形式为:
类型说明符  *指针变量名;
其中类型说明符表示所指数组的类型。从一般形式可以看出指向数组的指针变量和指向普通变量的指针变量的说明是相同的。
10.3.2	通过指针引用数组元素
C语言规定:如果指针变量p已指向数组中的一个元素,则p+1指向同一数组中的下一个元素。
引入指针变量后,就可以用两种方法来访问数组元素了。
如果p的初值为&a[0],则:
1)	p+i和a+i就是a[i]的地址,或者说它们指向a数组的第i个元素。
 
2)	*(p+i)或*(a+i)就是p+i或a+i所指向的数组元素,即a[i]。例如,*(p+5)或*(a+5)就是a[5]。
3)	指向数组的指针变量也可以带下标,如p[i]与*(p+i)等价。
根据以上叙述,引用一个数组元素可以用:
1)	下标法,即用a[i]形式访问数组元素。在前面介绍数组时都是采用这种方法。
2)	指针法,即采用*(a+i)或*(p+i)形式,用间接访问的方法来访问数组元素,其中a是数组名,p是指向数组的指针变量,其处值p=a。
【例10.9】输出数组中的全部元素。(下标法)
main(){
  int a[10],i;
  for(i=0;i<10;i++)
    a[i]=i;
  for(i=0;i<5;i++)
    printf("a[%d]=%d\n",i,a[i]);
}
 
【例10.10】输出数组中的全部元素。(通过数组名计算元素的地址,找出元素的值)
main(){
  int a[10],i;
  for(i=0;i<10;i++)
    *(a+i)=i;
  for(i=0;i<10;i++)
    printf("a[%d]=%d\n",i,*(a+i));
}
 
【例10.11】输出数组中的全部元素。(用指针变量指向元素)
main(){
  int a[10],I,*p;
  p=a;
  for(i=0;i<10;i++)
    *(p+i)=i;
  for(i=0;i<10;i++)
    printf("a[%d]=%d\n",i,*(p+i));
}
 
【例10.12】
main(){
  int a[10],i,*p=a;
  for(i=0;i<10;){
    *p=i;
    printf("a[%d]=%d\n",i++,*p++);
  }
}
 
几个注意的问题:
1)	指针变量可以实现本身的值的改变。如p++是合法的;而a++是错误的。因为a是数组名,它是数组的首地址,是常量。
2)	要注意指针变量的当前值。请看下面的程序。
【例10.13】找出错误。
main(){
  int *p,i,a[10];
  p=a;
for(i=0;i<10;i++)
    *p++=i;
  for(i=0;i<10;i++)
    printf("a[%d]=%d\n",i,*p++);
}
 
【例10.14】改正。
main(){
  int *p,i,a[10];
  p=a;
for(i=0;i<10;i++)
*p++=i;
  p=a;
  for(i=0;i<10;i++)
    printf("a[%d]=%d\n",i,*p++);
}
 
3)	从上例可以看出,虽然定义数组时指定它包含10个元素,但指针变量可以指到数组以后的内存单元,系统并不认为非法。
4)	*p++,由于++和*同优先级,结合方向自右而左,等价于*(p++)。
5)	*(p++)与*(++p)作用不同。若p的初值为a,则*(p++)等价a[0],*(++p)等价a[1]。
6)	(*p)++表示p所指向的元素值加1。
7)	如果p当前指向a数组中的第i个元素,则
*(p--)相当于a[i--];
*(++p)相当于a[++i];
*(--p)相当于a[--i]。
10.3.3	数组名作函数参数
数组名可以作函数的实参和形参。如:
 
main()
{int array[10];
   ……
   ……
 f(array,10);
……
    ……
}

f(int arr[],int n);
     {
……
    ……
}
array为实参数组名,arr为形参数组名。在学习指针变量之后就更容易理解这个问题了。数组名就是数组的首地址,实参向形参传送数组名实际上就是传送数组的地址,形参得到该地址后也指向同一数组。这就好象同一件物品有两个彼此不同的名称一样。
 
    同样,指针变量的值也是地址,数组指针变量的值即为数组的首地址,当然也可作为函数的参数使用。
【例10.15】
float aver(float *pa);
main(){
  float sco[5],av,*sp;
  int i;
  sp=sco;
  printf("\ninput 5 scores:\n");
  for(i=0;i<5;i++) scanf("%f",&sco[i]);
  av=aver(sp);
  printf("average score is %5.2f",av);
}
float aver(float *pa)
{
  int i;
  float av,s=0;
  for(i=0;i<5;i++) s=s+*pa++;
  av=s/5;
  return av;
}
 
【例10.16】将数组a中的n个整数按相反顺序存放。
算法为:将a[0]与a[n-1]对换,再a[1]与a[n-2] 对换……,直到将a[(n-1/2)]与a[n-int((n-1)/2)]对换。今用循环处理此问题,设两个“位置指示变量”i和j,i的初值为0,j的初值为n-1。将a[i]与a[j]交换,然后使i的值加1,j的值减1,再将a[i]与a[j]交换,直到i=(n-1)/2为止,如图所示。
 
程序如下:
void inv(int x[],int n)   /*形参x是数组名*/
{
 int temp,i,j,m=(n-1)/2;
 for(i=0;i<=m;i++)
{j=n-1-i;
   temp=x[i];x[i]=x[j];x[j]=temp;}
 return;
}
main()
{int i,a[10]={3,7,9,11,0,6,7,5,4,2};
 printf("The original array:\n");
 for(i=0;i<10;i++)
   printf("%d,",a[i]);
 printf("\n");
 inv(a,10);
 printf("The array has benn inverted:\n");
 for(i=0;i<10;i++)
  printf("%d,",a[i]);
 printf("\n");
}
 
对此程序可以作一些改动。将函数inv中的形参x改成指针变量。
【例10.17】对例10.16可以作一些改动。将函数inv中的形参x改成指针变量。
程序如下:
void inv(int *x,int n)   /*形参x为指针变量*/
{
 int *p,temp,*i,*j,m=(n-1)/2;
 i=x;j=x+n-1;p=x+m;
 for(;i<=p;i++,j--)
{temp=*i;*i=*j;*j=temp;}
 return;
}
main()
{int i,a[10]={3,7,9,11,0,6,7,5,4,2};
 printf("The original array:\n");
 for(i=0;i<10;i++)
   printf("%d,",a[i]);
 printf("\n");
 inv(a,10);
 printf("The array has benn inverted:\n");
 for(i=0;i<10;i++)
  printf("%d,",a[i]);
 printf("\n");
}
 
运行情况与前一程序相同。
【例10.18】从0个数中找出其中最大值和最小值。
调用一个函数只能得到一个返回值,今用全局变量在函数之间“传递”数据。程序如下:
int max,min;      /*全局变量*/
void max_min_value(int array[],int n)
{int *p,*array_end;
 array_end=array+n;
 max=min=*array;
 for(p=array+1;p<array_end;p++)
   if(*p>max)max=*p;
   else if (*p<min)min=*p;
 return;
}
main()
{int i,number[10];
 printf("enter 10 integer umbers:\n");
 for(i=0;i<10;i++)
   scanf("%d",&number[i]);
 max_min_value(number,10);
 printf("\nmax=%d,min=%d\n",max,min);
 }
 
说明:
1)	在函数max_min_value中求出的最大值和最小值放在max和min中。由于它们是全局,因此在主函数中可以直接使用。
2)	函数max_min_value中的语句:
max=min=*array;
array是数组名,它接收从实参传来的数组numuber的首地址。
*array相当于*(&array[0])。上述语句与 max=min=array[0];等价。
3)	在执行for循环时,p的初值为array+1,也就是使p指向array[1]。以后每次执行p++,使p指向下一个元素。每次将*p和max与min比较。将大者放入max,小者放min。
 
4)	函数max_min_value的形参array可以改为指针变量类型。实参也可以不用数组名,而用指针变量传递地址。
【例10.19】程序可改为:
int max,min;      /*全局变量*/
void max_min_value(int *array,int n)
{int *p,*array_end;
 array_end=array+n;
 max=min=*array;
 for(p=array+1;p<array_end;p++)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -