《C程序设计》课程学习(13)——第十章 指针(另一个版本)

    指针是c语言中比较灵活的数据结构,灵活地运用指针可以:  

(1) 有效地表示复杂的数据结构.  

(2) 动态分配内存.  

(3) 更方便地使用字符串和数组.  

(4) 直接处理内存地址.

§10.1    地址和指针的概念

1、 地址的概念

 “地址”:每个内存单元(字节) 的编号。

 “值”:内存单元中存入的内容。

2、对内存单元的存取有两种方式  

(1)直接访问:直接访问变量内容。  

(2)间接访问:借助中间变量。

 指针变量的概念

    指针就是地址。如果有一个变量专门用来存放另一个变量的地址(即指针),则它称为“指针变量”。

§10.2  变量的指针和指向变量的指针变量

注:

(1) 定义变量时标识符前面的“*”,表示该变量为指针变量,但指针变量名是p1、p2、p3,而不是*p1、*p2、*p3。

(2) 程序语句中"*" 表示"指向"。

(3) 指针变量只能指向同一个类型的变量。

2、指针变量的引用

 &——取址运算符:获取内存单元的地址  

 *——指针运算符:获取内存单元的内容

例10.1

3、指针变量作为函数参数

例:读程序,写结果

10.3   数组与指针

概念

    数组的指针是指数组的起始地址

    数组元素的指针是指数组元素的地址

例10.5 输出数组全部元素(设a数组,整型,10个元素)

上图是动态图,具体可以自己推理。

(2)下标法

main ( )
{int a[10];
  int  i;
  for (i=0;i<10;i++)
    scanf("%d",&a[i]);
  printf("\n");
  for (i=0;i<10;i++)
     printf("%3d",a[i]);
  }

(3)地址法

main ( )
{int a[10];
  int  i;
  for (i=0;i<10;i++)
    scanf("%d",a+i);
  printf("\n");
  for (i=0;i<10;i++)
     printf("%3d",*(a+i));
  }

数组名作函数参数

    用数组名作参数,在调用函数时实际上是把数组的首地址传给形参,这样实参与形参共同指向同一段内存。因而调用过程中,如形参数组元素值发生变化也就使实参数组的元素发生了变化,但这种变化并不是从形参传回实参的,而是由于形参与实参共享同一段内存而造成的。

例10.7  将数组a中n个整数按逆序存放。

    如果有一个实参数组,想在函数中改变此数组的元素的值,实参与形参的对应关系有以下几类情况:

(1) 形参和实参都用数组名:传递的是实参数组首地址,形参与实参共用同一段内存单元。

(2) 实参用数组名,形参用指针变量:通过指针变量值的改变可以指向实参数组的任一元素。

(3) 实参和形参都用指针变量:先使实参指针变量指向数组的首地址,然后将实参的值传给形参,通过指针变量值的改变可以使其指向数组的每个元素。

(4) 实参为指针变量,形参为数组名:设p为指针变量,令p=&a[0],p为实参,对应的形参x为数组名,则函数调用时将 p的值传给形参数组名x,也就是使其取得a数组的首地址,使 x数组和 a数组共用同一段内存单元。

例10.9  用选择法对10个整数排序。

(1) 实参用指针变量,形参用数组名

void  sort(int x[],int n)
{int i,j,k,t;
  for (i=0;i<n-1;i++)
  { k=i;
     for (j=i+1;j<n;j++)
        if (x[j]>x[k]) k=j;
     if (k!=i)
   {t=x[i];x[i]=x[k];x[k]=t;}
     }
  }
main ( )
{ int *p,i,a[10];
   p=a;
  for (i=0;i<10;i++)
     scanf("%d",p++);
   p=a;
   sort(p,10);
   for (p=a,i=0;i<10;i++)
      printf("%d",*p++);
 }

(2) 实参用数组名,形参用指针变量

void sort(int *x,int n)
{int i,j,k,t;
  for (i=0;i<n-1;i++)
    { k=i;
       for (j=i+1;j<n;j++)
           if (*(x+j)>*(x+k)) k=j;
       if (k!=i)
       { t=*(x+i);
         *(x+i)=*(x+k);
         *(x+k)=t;}
       }
  }
main ( )
{ int i,a[10];
  for (i=0;i<10;i++)
     scanf("%d",&a[i]);
   sort(a,10);
   for (i=0;i<10;i++)
      printf("%3d",a[i]);
}

(3)实参用指针变量,形参也用指针变量

void sort(int *x,int n)
{int i,j,k,t;
  for (i=0;i<n-1;i++)
    { k=i;
       for (j=i+1;j<n;j++)
           if (*(x+j)>*(x+k)) k=j;
       if (k!=i)
       { t=*(x+i);
         *(x+i)=*(x+k);
         *(x+k)=t;}
       }
  }
main ( )
{ int *p,i,a[10];
   p=a;
  for (i=0;i<10;i++)
     scanf("%d",p++);
   p=a;
   sort(p,10);
   for (p=a,i=0;i<10;i++)
      printf("%d",*p++);
    }

例: 从10个数中找出其中最大值和最小值。

方法2:

 main( )
 {int  i, a[10], max, min, *p1, *p2;
  void fun(int b[], int n, int  *a1, int  *a2 ) ;
   for (i=0;i<10;i++)
      scanf("%d",&a[i]);
  max=min=a[0];
  p1=&max;  p2=&min;
  fun(a, 10, p1, p2);
  printf("max=%d,min=%d\n",*p1,*p2);
  }
 void fun(int  b[], int  n, int *a1,  int *a2)
 { int i;
   for (i=1;i<n;i++)
      if (b[i]>*a1) *a1=b[i];
      else if (b[i]<*a2) *a2=b[i];
   }

指针变量处理二维数组

1.二维数组的地址

 2.二维数组的指针

 (1) 指向数组元素的指针变量。

例:用指针变量输出数组元素a[i][j]的值。

  main( )
  { int a[2][3]={2,3,6,7,8,5};
   int i,j,*p;
   p=a; 
   scanf("%d %d",&i,&j);
   printf("%3d",*((p+i*3)+j));
   }

(2) 指向由m个整数组成的一维数组的指针变量。

例10.12   输出二维数组任一行任一列的元素的值。

 main ( )
{ int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
  int (*p)[4],i,j;
  p=a;
  scanf("i=%d,j=%d",&i,&j);
  printf("a[%d,%d]=%d\n'',i,j,*(*(p+i)+j));
   }

(3) 二维数组的指针作函数参数。 

例 求二维数组a[4][5]每列最大值

§10.4     字符串的指针和指向字符串的指针变量

  字符串的表示形式

     1.字符数组

    例

            main
            {static char string[ ]="I Love China!";
              printf("%s\n",string);
             }

 2.字符串指针

    例

            main
            {char  *string="I Love China!";
              printf("%s\n",string);           
             }

例10.17   将字符串a复制到字符串b中。

方法1:

  main ( )
  { static char a[]="I am a boy.",b[20];
     int i;
     for (i=0;*(a+i)!='\0';i++)
         *(b+i)=*(a+i);
     *(b+i)='\0';
     printf ("string a is :%s\n",a);
     printf ("string b is :%s\n",b);
     }

方法2:

字符串指针作函数参数

例10.19  用函数调用实现字符串的复制。

方法1:

void  copy_string(char from[],char to[])
{ int i=0;
   while(from[i]!='\0')
       { to[i]=from[i];i++;}
   to[i]='\0'; }
main( )
{static char a[ ]="I am a teacher.";
  static char b[ ]="You are a student.";
  printf("string_a=%s\nstring_b=%s\n",a,b);
  copy_string(a,b);
  printf("string_a=%s\nstring_b=%s\n",a,b);
  }

方法2:

例:  有一个长度不大于40的字符串,已知其中总包 含两个字符"A",求处于两个字符"A"中间的字符个数, 及这些字符.

#include”stdio.h”
 int  f(char *x,char *y)
  { int  i, n=0,j;
   for(i=0;*(x+i)!='\0';i++)
      if(*(x+i)=='A')  break;
   for(j=i+1;*(x+j)!=‘A’;j++)
    {  *(y+n)=*(x+i);    n++;};
   *(y+n)='\0';
   return(n);
 }
 main( )
 { char a[40],b[40];
   int n;
   gets(a);
   n=f(a,b);
   printf(“n=%d\n",n);
   puts(b);
   }

 字符指针变量与字符数组的区别

1.字符指针变量中存放的是地址,决不是将字符串放到字符指针变量中。

2.赋值方式:对数组只能各个赋值或者直接初始化。

3.指针变量可以指向一个字符型数据,但如果未对它赋以一个地址值,则它并未具体指向哪一个字符数据。

4.指针变量的值是可以改变的,而数组名所指的地址是固定的

5.用指针变量指向一个格式字符串。

例: 有两个字符串str1,str2, 编程序将str1,str2 中对应字符较大的放到数组str3中.

 void ccc(char *s1,char *s2,char *s3)
 {int i;
  for(i=0;*(s1+i)!='\0'&&*(s2+i)!='\0';i++)
    *(s3+i)=*(s1+i)>*(s2+i)?*(s1+i):*(s2+i);
  if(*(s1+i)=='\0')
    while(*(s2+i)!='\0') {*(s3+i)=*(s2+i);i++;}
  if(*(s2+i)=='\0')
    while(*(s1+i)!='\0') {*(s3+i)=*(s1+i);i++;}
  *(s3+i)='\0';
   }
 main()
 {char *str1="Chinese",*str2="India",str3[40];
  ccc(str1,str2,str3);
  puts(str3);
   }

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值