C语言非常道
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

4.5 返回指针的函数

函数不但可以具有指针类型的参数,它的返回类型也可以是指针。在下面的程序中,函数swaprp交换两个参数所指向的变量的值,并返回一个指针,该指针指向值较大的那个变量。

              /***********c0404.c***********/
              char * swaprp(char * a, char * b)
              {
                  char temp = * a;
                  * a = * b;
                  * b = temp;

                  return * a > * b ? a : b;
              }

              int main(void)
              {
                  char m = 102, n = 103, * pc;

                  pc = swaprp(& m, & n);
              }

如图4-7所示,因为标识符swaprp看上去既可以与星号“*”进行语法关联,也可以与括号“(”进行语法关联,但括号的优先级比星号高,所以,对函数swaprp的声明应当这样解读:它的类型是函数,第一个参数是char *类型的变量a,第二个参数是char*类型的变量b,该函数返回一个指针,指向char。当然,也可以直接说是返回一个指向char的指针。

图4-7 声明一个函数,该函数的返回类型是指针

在函数swaprp里,变量值的交换和前面相比没有什么不同,唯一的变化是多了一个奇怪的return语句:

              return * a > * b ? a : b;

因为函数swaprp的返回类型不是void,所以这里是返回表达式* a>* b ? a :b的值。这是一个我们没见过的表达式,称为条件表达式。条件表达式由三个表达式E1、E2、E3,以及条件运算符?和:按下述方式组合而成:

              E1 ? E2 : E3

再来看表达式* a>* b ? a : b,这里涉及三个运算符,其优先级从高到低依次为一元*运算符、关系运算符>和条件运算符?:,所以这是一个条件表达式,等价于((*a)>(* b))? a : b。

条件表达式的求值过程是这样的:先求值E1,如果E1的值不为0,则求值E2,且整个条件表达式的值来自E2;如果E1的值为0,则求值E3,且整个条件表达式的值来自E3。例如,条件表达式5 ? 6 : 7的值是6,而0 ? 8 : 9的值是9。

这样一来,return语句的功能就很清楚了:表达式* a和* b都是左值,先进行左值转换,关系运算符对左值转换后的值进行比较,若结果为1,则整个条件表达式的值是左值a经左值转换后得到的指针;若结果为0,则整个条件表达式的值是左值b经左值转换后得到的指针。最后,return语句返回条件表达式的值(指针)给它的调用者。取决于比较的结果,返回的指针指向main函数内的变量,要么是变量m,要么是变量n。

再来看main函数,我们声明了一个指针类型的变量pc,并用它来接受函数swaprp的返回值。因为pc是指向char的指针,而函数swaprp的返回值也是指向char的指针,类型一致,可以赋值。

练习4.4

1.在程序中添加一个char类型的变量c,并用函数swaprp的返回值所指向的变量的值初始化它。

2.以下,函数cusum用于计算从1加到N的和,N是非负整数。参数sum用于接受一个指针,累加的结果保存在该指针所指向的变量里;参数r也用于接受一个指针,该指针所指向的变量里保存了所要累加的最大值。如果这个值是0或者大于1000000000,则函数返回0,否则返回1。现在请按上述要求将函数体补充完整,并上机验证程序的编写是否正确。

              _Bool cusum(unsigned long long int * sum, unsigned long long int * r)
              {

              }

3.以下类型中,属于变量类型的是_______;属于函数类型的是_______。

(a)char

(b)main函数

(c)_Bool

(d)signed int

(e)指针

4.若* E是合法的表达式,则该表达式的结果不可能是_______。

(a)值

(b)左值

(c)代表一个变量

(d)代表E(的值)所指向的那个变量

5.在表达式& E中,E必须是_____,如果E的类型是int,则&E的结果类型是_____。

(a)值

(b)左值或者函数指示符

(c)指向int的指针

(d)int