从头学C(32)函数的基本知识

0

从这一节开始,我们就进入了《第四章 函数与程序结构》的学习。对于代码的易读性、程序结构的清晰等方面,函数都发挥着重要的作用。它可以把大的计算任务分解成若干个较小的任务,同时还可以做到代码复用,隐藏操作细节,大大降低程序修改的难度。

可以说,C语言程序一般都是由许多小的函数组成,而不是少量庞大的函数组成。

在前面的章节从头学C(8)函数中,我们已经学习了函数的一些基本知识。比如目前C语言允许在声明函数时同时声明参数的类型,这样编译器就有可能检测出声明与定义类型不一致等等错误;如果参数声明得当,程序还可以自动进行强制类型转换。

除了函数和程序结构,本章后续章节还会学习到名字的作用域规则以及预处理的功能,包括条件编译、宏扩展等等。

第四章 函数与程序结构 >> 4.1 函数的基本结构

首先来设计一个程序:给定多行字符串,从里面查找包含特定“模式”或特定“字符串”的行,并将找到的这些行打印出来。

因此,我们可以将程序按如下思路设计:

while(还有未处理的行)
        if(该行包含指定的字符串)
                打印该行

虽然我们可以把所有代码都放到主程序main中,但更合适的做法是将上面三部分都设计成一个独立的函数,这样的程序结构显然更清晰简洁,而且这三个独立的函数还可提供给其他程序进行复用,方便开发其他类似的程序。

“还有未处理的行”可以用函数getline()来实现,这个函数可以从第一章中拿来借鉴。

“该行包含指定的字符串”用函数strindex(s,t)来实现,需要我们自己来编写。该函数返回字符串 t 在字符串 s 中出现的起始位置或索引( index )。当 s 不包含 t 时,程序返回 -1,因此可以用这个值来表示失败的情况。

“打印该行”可以直接用printf()函数实现,这个函数我们前面已经用了很多次了。

有了思路,程序实现就应该是下面这个样子了:

#include <stdio.h>

#define MAXLINE 1000    /* maximum input line length */

int my_getline(char line[], int max);
int strindex(char source[], char searchfor[]);

char pattern[] = "ould"; /* pattern to search for */

/* find all lines matching pattern */
main()
{
        char line[MAXLINE];
        int found = 0;

        while (my_getline(line, MAXLINE) > 0)
                if (strindex(line, pattern) >= 0)
                {   
                        printf("%s", line);
                        found ++; 
                }   
        return found;
}

/* my_getline: get line into s, return length */
int my_getline(char s[], int lim)
{
        int c, i;

        i = 0;
        while (--lim > 0 && (c=getchar()) != EOF && c != '\n')
                s[i++] = c;
        if (c == '\n')
                s[i++] = c;
        s[i]= '\0';
        return i;
}

/* strindex: return index of t in s, -1 if none */
int strindex(char s[], char t[])
{
        int i, j, k;

        for (i = 0; s[i]!= '\0'; i++)
        {
                for (j=i, k=0; t[k]!='\0' && s[j]==t[k]; j++, k++)
                        ;
                if (k > 0 && t[k]== '\0')
                        return i;
        }
        return -1;
}

函数的定义形式:

返回值类型 函数名(参数声明列表)
{
        声明和语句
}

以上除了函数名,其他部分都可以省略。如果省略了“返回值类型”,则默认返回值类型是 int。

被调用的函数通过 return 语句向调用者返回值,return 后面可以跟任何表达式:

return 表达式;

有几个地方要注意:

  1. 必要时,表达式会被转换为函数声明的返回值类型。
  2. 调用函数也可以忽略返回值。
  3. return 语句中的表达式也可以忽略(如果 return 语句后面没有表达式,函数将不会向调用者返回任何值)。

上面的 main 函数返回了一个状态,即匹配的行数,该返回值可以给调用本程序的环境使用。

Leave A Reply