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

📄 tc12.dat

📁 C++指令字典 一个方便的软件 用于C++指令的查询
💻 DAT
字号:
第9章  指  针(下)

9.4   字符串的指针和指向字符串的指针变量

字符串在内存中的起始地址称为字符串的指针,可以定义一个字符指针变量指向一个字符串.

9.4.1  字符串的表示与引用

在C语言中,既可以用字符数组表示字符串,也可用字符指针变量来表示;引用时,既可以逐个字符引用,也可以整体引用.

1.逐个引用

[案例9.8] 使用字符指针变量表示和引用字符串.

/*案例代码文件名:AL9_8.C*/

main()

   { char *string=”I love Beijing.”; 

      for(; *string!=’\0’; string++) printf(“%c”, *string);

      printf(“\n”);

   }                                                

程序运行结果:

        I love Beijing.

程序说明:char *string="I love Beijing.";语句

定义并初始化字符指针变量string:用串常量“I love Beijing.”的地址(由系统自动开辟、存储串常量的内存块的首地址)给string赋初值.

该语句也可分成如下所示的两条语句:

 char *string;

 string="I love Beijing.";

注意:字符指针变量string中,仅存储串常量的地址,而串常量的内容(即字符串本身),是存储在由系统自动开辟的内存块中,并在串尾添加一个结束标志’\0’.

2.整体引用

[案例9.9] 采取整体引用的办法,改写[案例9.8].

/*案例代码文件名:AL9_9.C*/

/*程序功能:使用字符指针变量表示和引用字符串*/

main()

    { char *string=”I love Beijing.”; 

       printf(“%s\n”,string);

     }                                [程序演示]

程序说明:printf("%s\n",string);语句

通过指向字符串的指针变量string,整体引用它所指向的字符串的原理:系统首先输出string指向的第一个字符,然后使string自动加1,使之指向下一个字符;重复上述过程,直至遇到字符串结束标志.

注意:其它类型的数组,是不能用数组名来一次性输出它的全部元素的,只能逐个元素输出.

例如:

    int array[10]={……};

    ......

    printf("%d\n",array);            /*这种用法是非法的*/

    ......

3.字符指针变量与字符数组之比较

虽然用字符指针变量和字符数组都能实现字符串的存储和处理,但二者是有区别的,不能混为一谈.

(1)存储内容不同.

字符指针变量中存储的是字符串的首地址,而字符数组中存储的是字符串本身(数组的每个元素存放一个字符).

(2)赋值方式不同.

对字符指针变量,可采用下面的赋值语句赋值:

       char  *pointer;

        pointer="This is a example.";

而字符数组,虽然可以在定义时初始化,但不能用赋值语句整体赋值.下面的用法是非法的:

       char  char_array[20];

        char_array="This is a example.";         /*非法用法*/

(3)指针变量的值是可以改变的,字符指针变量也不例外;而数组名代表数组的起始地址,是一个常量,而常量是不能被改变的.

9.4.2  字符串指针作函数参数

[案例9.10] 用函数调用方式,实现字符串的复制.

/*案例代码文件名:AL9_10.C*/

/**********************************************************/

/*string_copy()函数:复制一个字符串                         */

/*形参:字符指针str_from接收源串,字符指针 str_to存储目标串 */

/*返回值:无                                              */

/**********************************************************/

void string_copy(char *str_from, char *str_to)

    { int i=0;

       for(; (*(str_to+i)=*(str_from+i))!=’\0’; i++) ; /*循环体为空语句*/

    }

main()

  {char array_str1[20]=”I am a teacher.”;

     char array_str2[20];

     string_copy(array_str1, array_str2); /*数组名作实参*/

     printf(“array_str2=%s\n”, array_str2);

  }

程序运行结果:

        I am a teacher.

程序说明:for(; (*(str_to+i)=*(str_from+i))!=’\0’; i++) ; 

语句的执行过程为:首先将源串中的当前字符,复制到目标串中;然后判断该字符(即赋值表达式的值)是否是结束标志.如果不是,则相对位置变量i的值增1,以便复制下一个字符;如果是结束标志,则结束循环.其特点是:先复制、后判断,循环结束前,结束标志已经复制.

在C语言中,用赋值运算符、而不是赋值语句来实现赋值操作,能给某些处理带来很大的灵活性,该语句(实现字符串的复制)的用法就是最好的例证.

9.5   返回指针值的函数

  一个函数可以返回一个int型、float型、char型的数据,也可以返回一个指针类型的数据. 返回指针值的函数(简称指针函数)的定义格式如下:

         函数类型   *函数名([形参表])


        [案例9.11] 某数理化三项竞赛训练组有3个人,找出其中至少有一项成绩不合格者.要求使用指针函数实现.
/*案例代码文件名:AL9_11.C*/

/*************************************************************/
/*seek()函数:判断是否有不合格成绩                                   */
/*形参:指向由3个int型元素组成的1维数组的行指针变量                 */
/*返回值:(1)有不合格成绩,则返回指向本行首列的一个(列)指针;    */
/*               (2)没有有不合格成绩,返回值为指向下一行的一个(列)指针 */
/*************************************************************/

int  *seek( int  (*pnt_row)[3] )

   { int i=0, *pnt_col;            /*定义一个(列)指针变量pnt_col */

      pnt_col=*(pnt_row+1);    /*使pnt_col指向下一行之首(作标志用)*/

      for(; i<3; i++)

          if(*(*pnt_row+i)<60)   /*某项成绩不合格*/

             { pnt_col=*pnt_row; /*使pnt_col指向本行之首*/

                break;            /*退出循环*/

             }

      return(pnt_col);

  }

/*主函数main()*/

main()

    { int grade[3][3]={{55,65,75},{65,75,85},{75,80,90}};

       int i,j,*pointer;                          /*定义一个(列)指针变量pointer */

       for(i=0; i<3; i++)             /*控制每个学生*/

            { pointer=seek(grade+i);          /*用行指针作实参,调用seek()函数*/

               if(pointer==*(grade+i))      /*该学生至少有一项成绩不合格*/

                    { /*输出该学生的序号和各项成绩*/

                       printf(“No.%d grade list: ”, i+1); 

                       for(j=0; j<3; j++) printf(“%d  ”,*(pointer+j));

                       printf(“\n”);

                    }

             }

      }                                                   [程序演示]

程序运行结果:

No.1 grade list: 55  65  75

程序说明:

(1) 主函数中的pointer=seek(grade+i);语句

调用seek()函数时,将实参grade+i(行指针)的值,复制到形参pnt_row(行指针变量)中,使形参pnt_row指向grade数组的第i行.

(2)在指针函数seek()中:

 1) pnt_col=*(pnt_row+1);语句

*(pnt_row+1)将行指针转换为列指针,指向grade数组的第i+1行第0列,并赋值给(列)指针变量pnt_col.

2) if(*(*pnt_row+i)<60)行

pnt_row是一个行指针,指向数组grade的第i行;*pnt_row使指针由行转换为列,指向数组grade的第i行0列;*pnt_row+j的值还是一个指针,指向数组的第i行第j列;*(*pnt_row+j)是一个数据(数组元素grade[i][j]的值).

9.6  指针数组与主函数main()的形参

9.6.1  指针数组
        1.概念
       数组的每个元素都是一个指针数据.指针数组比较适合用于指向多个字符串,使字符串处理更加方便、灵活.
        2.定义格式

        数据类型  *数组名[元素个数]
        注意:与行指针变量定义格式“<数据类型>(*行指针变量)[<元素个数>]”的差别.


        [案例9.12] 有若干计算机图书,请按字母顺序,从小到大输出书名.解题要求:使用排序函数完成排序,在主函数中进行输入输出.
/*案例代码文件名:AL9_12.C*/
/*程序功能:指针数组应用示例*/

/***********************************************/

/* sort()函数:对字符指针数组进行排序            */

/*形参:name--字符指针数组,count--元素个数*/

/*返回值:无                                   */

/***********************************************/

void  sort(char *name[], int count)

   { char *temp_p;

      int i,j,min;

      /*使用选择法排序*/

     for(i=0; i<count-1; i++)                          /*外循环:控制选择次数*/

        { min=i;                                   /*预置本次最小串的位置*/

          for(j=i+1; j<count; j++)                /*内循环:选出本次的最小串*/

               if(strcmp(name[min],name[j])>0)         /*存在更小的串*/

                   min=j;                                   /*保存之*/

           if(min!=i)                                    /*存在更小的串,交换位置*/

                temp_p=name[i],name[i]=name[min],name[min]=temp_p;

          }

     }

/*主函数main()*/

main()

   { char *name[5]={“BASIC”,”FORTRAN”,”PASCAL”,”C”,”FoxBASE”};

      int i=0;

      sort(name,5);     /*使用字符指针数组名作实参,调用排序函数sort()*/

       /*输出排序结果*/

       for(; i<5; i++) printf(“%s\n”,name[i]);

    }                                                                 [程序演示]

程序运行结果:

BASIC

C

FORTRAN

FoxBASE

PASCAL

程序说明:

(1)实参对形参的值传递:

               sort(  name  ,     5 );

                          ↓          ↓

void sort(char *name[], int count)

(2)字符串的比较只能使用strcmp()函数.形参字符指针数组name的每个元素,都是一个指向字符串的指针,所以有strcmp(name[min],name[j]).

9.6.2  主函数main()的形参

在以往的程序中,主函数main()都使用其无参形式.实际上,主函数main()也是可以指定形参的.

[案例9.13] 用同一程序实现文件的加密和解密.约定:程序的可执行文件名为lock.exe, 其用法为:lock +|- <被处理的文件名>,其中“+”为加密,“-”为解密.

/*案例代码文件名:AL9_13.C*/

/*程序功能:带参主函数的应用示例*/

main(int argc, char *argv[])

   { char c;

      if (argc != 3) printf("参数个数不对!\n");

      else

         { c=*argv[1];           /*截取第二个实参字符串的第一个字符*/

            switch(c)

         { case '+':             /*执行加密*/

                   { /*加密程序段*/

                      printf("执行加密程序段.\n");

                    }

                    break;

              case '-':                 /*执行解密*/

                    { /*解密程序段*/

                       printf("执行解密程序段.\n");

                     }

                     break;

                       default: printf("第二个参数错误!\n");

                   }

             }

}                                         

1.主函数main()的有参形式

            main(int argc, char *argv[])

                  { … …}

2.实参的来源

运行带形参的主函数,必须在操作系统状态下,输入主函数所在的可执行文件名,以及所需的实参,然后回车即可.

命令行的一般格式为:

        可执行文件名

⌨️ 快捷键说明

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