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

📄 05章 指针与字符串.txt

📁 C++大学教程txt版中文版 C++大学教程txt版中文版
💻 TXT
📖 第 1 页 / 共 5 页
字号:
50        for ( int column = 0; column <= 12; column++ )
51
52  if ( wDeck[ row][ column ]  = card )
53     cout << setw(8) << setiosflags( ios::right )
54          << wFace[ column ] <<" of"
55           << setw( 8 ) << setiosflags( ios::left )
56           << wSuit[ row ]
57           << ( card % 2 == 0 ? ,'\n' : '\t' );
58 }

输出结果:
     Six of Clubs              Seven of Diamonds
        Ace of Spades               Ace of Diamonds
        Ace of Hearts             Queen of Diamonds
     Queen of Clubs              Seven of Hearts
        Ten of Hearts              Deuce of Clubs
        Ten of Spades              Three of Spades
        Ten of Diamonds             Four of Spades
       Four of Diamonds              Ten of Clubs
        Six of Diamonds              six of Spades
     Eight of Hearts             Three of Diamonds
      Nine of Hearts             Three of Hearts
     Deuce of Spades               six of Hearts
       Five of Clubs              Eight of Clubs
     Deuce of Diamonds            Eight of Spades
       Five of Spades              King of Clubs
       King of Diamonds             Jack of Spades
     Deuce of Hearts              Queen of Hearts
        Ace of Clubs               King of Spades
     Three of Clubs               King of Hearts
       Nine of Clubs               Nine of Spades
       Four of Hearts             Queen of Spades
     Eight of Diamonds             Nine of Diamonds
       Jack of Diamonds            Seven of Clubs
       Five of Hearts              Five of Diamonds
       Four of Clubs               Jack of Hearts
       Jack of Clubs              Seven of Spades
                        
                          图5.25  洗牌与发牌程序的执行结果

 发牌算法中有个缺点,一旦找到匹配之后,即使第一次就找到,两个内层的for结构仍然继续搜索deck中的其余元素。练习中要纠正这个缺点。

5.11  函数指针
    函数指针包含函数在内存中的地址。第4章介绍了数组名实际上是数组中第一个元素的内存地址。同样,函数名实际上是执行函数任务的代码在内存中的开始地址。函数指针可以传人函数、从函数返回、存放在数组中和赋给其他的函数指针。
    要演示如何使用函数指针,我们修改图5.15的冒泡排序程序,变成图5.26的程序。新程序包括main和函数bubble、swap、ascending和descending。函数bubbleSort接收ascending或descending函数的函数指针参数以及一个整型数组和数组长度。程序提示用户选择按升序或降序排序。如果用户输入1,则向函数bubble传递ascending函数的指针,使数组按升序排列。如果用户输入2,则向函数bubble传递descending函数的指针,使数组按降序排列。图5.27显示了示例的执行结果。

1 // Fig. 5.26: fig0526.cpp
2 // Multipurpose sorting program using function pointers
3 #include <iostream.h>
4 #include <iomanip.h>
5
6 void bubble( int [], const int, int (*)( int, int ) );
7 iht ascending( int, int );
8 int descending( int, int );
9
10 int main()
11 {
12   const int arraySize = 10;
13   int order,
14      counter,
15      a[ arraySize ] = { 2, 6, 4, 8, 10, 12, 89, 68, 45, 37 };
16
17   cout << "Enter 1 to sort in ascending order,\n"
18       << "Enter 2 to sort   descending order: ";
19   cin >> order;
20   cout << "\nData items in original order\n";
21
22   for ( counter = 0; counter < arraySize; counter++ )
23     cout << setw( 4 ) << a[ counter ];
24
25   if ( order == 1 ) {
26     bubble( a, arraySize, ascending );
27     cout << "\nData items in ascending order\n";
29    else {
30     bubble( a, arraySize, descending );
31     cout << "\nData items in descending order\n";
32   }
33
34   for ( counter = 0; coun er < arraySize; counter++ )
35     cout << setw( 4 )<< a[ counter ]
36
37   cout << endl;
38   return 0;
39 }
40
41 void bubble( int work[ ], const int size,
42           int (*compare)( int, int) )
43 {
44   void swap( int *, int* );
45
46   for ( int pass = 1; pass < size; pass++ )
47
48      for ( int count = 0; count < size - 1; count++ )
49
50  if( (*compare)( work[ count ], work[count + 1 ] ) )
51     swap( &work[ count ], &work[ count + 1 ] );
52 }
53
54 void swap( int *element1Ptr, int *element2Ptr )
55 {
56   int temp;
57
58   temp = *element1Ptr;
59   *element1Ptr = *element2Ptr;
60   *element2Ptr = temp;
65   return b < a;  // swap if b is less than a
66 }
67
68 int descending( int a, int b )
69 {
70    return b > a;  // swap if b is greater than a
71 }

                           图5.26  使用函数指针的多用途排序程序

  输出结果:
    Enter  1  to  sort  in  ascending  order,
    Enter  2  to  sort  in  descending  order:1
    Data  items  in  original  order
    2    6    4    8    1O    12    89    68    45    37
    Data  items  in  ascending  order
    2    4    6    8    1O    12    37    45    68    89
    Enter  1  to  sort  in  ascendinq  order,
    En(e[  2  to  sort  in  descending  order: 1
    Data  items  in  Oriqinal  order
    2    6    4    8    10    12    89    68    45    37
    Dats  items  in  ascendinQ  order
    89    68    45    37    12    10    9    6    4    2
    
                    图5.27  使用函数指针的多用途排序程序的执行结果

    注意这里只包括类型,程序员可以加上名称.但参数名只用于程序中的说明,编译器将其忽略。
    if语句中调用传人bubble的函数,如下所示:
    if(( *compare )( work[ count ], work[ count + 1 ]  ))
就像复引用变量指针可以访问变量值一样,复引用函数指针可以执行这个函数。
    也可以不复引用指针而调用函数,如下所示:
    if ( compare( work[ count ],work[ count + 1 ] )  )
直接用指针作为函数名。我们更愿意使用第一种通过指针调用函数的方法,因为它显式说明compare是函数指针,通过复引用指针而调用这个函数。第二种通过指针调用函数的方法使compare好像是个实际函数。程序用户可能搞糊涂,想看看compare函数的定义却怎么也找不到。
    函数指针的一个用法是建立菜单驱动系统,提示用户从菜单选择一个选项(例如从1到5)。每个选项由不同函数提供服务,每个函数的指针存放在函数指针数组中。用户选项作为数组下标,数组中的指针用于调用这个函数。
    图5.28的程序提供了声明和使用函数指针数组的一般例子。这些函数(function1、function2和function3)都定义成取整数参数并且不返回值。这些函数的指针存放在数组f中,声明如下:
    void(*f[ 3 ] )(int) = {  function1,  function2,function3}
声明从最左边的括号读起,表示f是3个函数指针的数组,各取整数参数并返回void。数组用三个函数名(是指针)初始化。用户输入0到2的值时,用这些值作为函数指针数组的下标。函数调用如下所示:
    (*f[ choice ])(choice);
调用时,f[choice]选择数组中choice位置的指针。复引用指针以调用函数,并将choice作为参数传人函数中。每个函数打印自己的参数值和函数名,表示正确调用了这个函数。练习中要开发一个菜单驱动系统。

1 // Fig. 5.28: fig05_28.cpp
2 // Demonstrating an array of pointers to functions
3 #include <iostream.h>
4 void functionl( int );
5 void function2( iht );
6 void function3( int );
7
8 int main()
9 {
10   void (* f[ 3 ] )( int ) = { function1, function2, function3 };
11   int choice;
12
13   cout << "Enter a number between 0 and 2, 3 to end: ";
14   cin >> choice;
15
16   while ( choice >= 0 && choice < 3 ) {
17      (* f[ choice ] )( choice );
18     cout << "Enter a number between 0 and 2, 3 to end: ";
19     cin >> choice;
2O   }
21
22   cout << "Program execution completed." << endl;
23   return 0;
24 }
25
26 void function1( int a )
27 {
28   cout << "You entered " << a
29          << "so function1 was called\n\n";
30 }
31
32 void function2( int b )
33 {
34   cout << "you entered " << b
35       << "so function2 was called\n\n";
34 }
37
38 void function3( int c )
39 {
40   cout << "You entered "<< c
41       << "so function3 was called\n\n";
42 }

输出结果:
Enter a number between 0 and 2, 3 to end: 0
You entered 0 so functionl was called
Enter a number between 0 and 2, 3 to end: 1
You entered 1 so function2 was called
Enter a number between 0 and 2, 3 to end: 2
You entered 2 so function3 was called
Enter a number between 0 and 2, 3 to end: 3
Program execution completed
                     
                             图5.28  声明和使用函数的指针数组
           

5.12  字符与字符串处理简介
 本节要介绍一些字符串处理的标准库函数。这里介绍的技术适用于开发文本编辑器、字处理器、桌面排版软件、计算机化打字系统和其他文本处理软件。我们这里使用基于指针的字符串,本书稍后还将介绍把字符串作为成熟的对象。

5.12.1  字符与字符串基础
字符是C++编程语言的基本组件。每个程序都是由一系列字符用有意义的方式组合而成的,计算机将其解释为一系列指令,用来完成一组任务。程序可能包含字符常量(character constant)。字符常量是表示为单引号字符的整数值。字符常量的值是机器字符集中该字符的整数值。例如,'z'表示z的整数值(在ASCII字符集中为122),'\n'表示换行符的整数值(在ASCII字符集中为10)。
字符串就是把—系列字符当作一个单元处理。字符串可能包含字母、数字和+、-、*、/、$等各种特殊字符(special character)。C++中的字符串直接量(string literal)或字符串常量(string constant)放在双引号中如下所示:
    ”John Q.Doe”    (姓名)
    ”9999 Nain Street”    (街道)
    ”Waltham,Massachusetts”    (州)
    ”(201)555—1212”    (电话号码)
    C++中的字符串是以null终止符('\0')结尾的字符数组。通过字符串中第一个字符的指针来访问字符串。字符串的值是字符串中第一个字符的地址(常量),这样,c++中可以说字符串是个常量指针,是指向字符串中第一个字符的指针。从这个意义上说,字符串像数组一样,因为数组名也是第一个元素的(常量)指针。
    可以在声明中将字符串指定为字符数组或char*类型的变量。下列声明:
    char color[]  = "blue";
    char *ColorPtr = "blue";
    分别将变量初始化为"blue"。第一个声明生成5个元素的数组color,包含字符'b'、'l'、'u'、'e'和'w'。第二个声明生成指针变量colorPtr,指向内存中的字符串"blue"。
    可移植性提示5. 5
    用字符串直接量初始化char*类型的变量时,有些编译器将字符串放在内存中无法修改字符串的位置。如果要修改字符串直接量,则应将其存放在字符数组中,以便在所有系统中修改。
    声明char color[]={"blue"};也可以改写成:
    char color[]  = {'b','l','u','e','\0'};
声明包含字符串的字符数组时,数组应足够大,能存放字符串及其null终止符。上述声明自动根据初始化值列表中提供的初始化值的个数确定数组长度。
    常见编程错误5.15
    字符数组中没有分配能存放字符串及其null终止符的足够空间。
    常见编程错误5.16
    生成或使用不包含null终止符的字符串。
    编程技技巧5.5
    在字符数组中存放字符串时,一定要保证能存放要存的最长字符串。C++允许存放任意长度的字符串。如果字符串长度超过字符数组长度,则越界字符会改写数组后面的内存地址中存放的数据。
    字符串可以用cin通过流读取赋给数组。例如,下列语句将字符串赋给字符数组word[20]:
    cin >> word;
用户输入的字符串存放在word中。上述语句读取字符,直到遇到空格、制表符、换行符或文件结束符。注意,字符串不能超过19个字符,因为还要留下nUll终止符的空间。第2章介绍的setw流操纵算

⌨️ 快捷键说明

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