2019-03-09 计算机二级C语言程序设计之对函数的进一步讨论

参考资料:高教版《全国计算机等级考试二级教程——C语言程序设计》

传给main函数的参数

可以在运行C 程序时,通过运行C程序的命令行把参数传送给C程序。

main函数通常可用两个参数,如:

main(int argc, char **argv);

其中argc和argv是两个参数名,可由用户自己命名,但它们的类型是固定的。第一个参数必须是整型,第二个参数必须是一个指向字符型的指针数组的指针,这个字符型指针数组的每个指针都指向一个字符串。

因此,第二个参数argv还可以直接定义成基类型为字符型的指针数组:

char *argv[];

对包含以上主函数的、名为myc的文件进行编译连接,生成名为myc.exe的可执行文件后,即可在命令提示符下输入命令“myc”来执行该程序。这就成为命令行,myc即为执行程序的命令。

这时argc中的值为1,argv[0]中将存放字符串“ myc”的首地址(即指向字符串 myc)。

命令行中,各参数之间用空格符或tab符隔开,空格符不作为参数的内容。

注:如果要把空格也作为参数的内容,应该把字符串放在一对双引号内。

例1 若以下程序存放在myc.c文件中,在编译连接后,生成一个myc.exe文件,输出argc和argv中的数据。

#include <stdio.h>

int main(int argc, char *argv[])
{
    int i;
    printf("argc = %d\n", argc);
    for(i = 1; i < argc; i++)
        printf("%s", argv[i]);
    printf("\n");
}

若在命令行中输入:

myc A COMMAND LINE \n (\n代表回车键)

程序将输出:

argc = 4
A COMMAND LINE

通过实参向函数传递函数名或指向函数的指针变量

指向函数指针变量的定义

在C语言中函数名代表该函数的入口地址,因此可以定义一种指向函数的指针来存放这种地址。例如:

#include <stdio.h>
double fun(int a, int *p)
{
    ……
}
int main(void)
{
    double (*fp)(int, int *), y;
    int n;
    
    fp = fun;
    ……
    y = (*fp)(56, &n);  //此处通过指向函数的指针调用fun函数
    ……
}

在这里,说明符(*fp)(int, int *)说明fp是一个指向函数的指针变量,这个函数必须是double类型。

注意:若写成fp(int, int ),则说明的fp就不是指针变量,而是说明fp是一个函数,该函数的返回值类型是基类型为double的指针类型**。

说明符后面一对圆括号中是类型名,用以说明所指函数的参数个数和参数的类型,这些类型名应该与所指函数参数的类型一一对应。

注意:如果函数没有形参,这一对圆括号也不可以省略。

表达式fp = fun把fun函数的地址赋予指针变量fp,此处fp的类型必须与fun的类型相同。

语句y = (*fp)(56, &n);实现对函数fun的调用,它与y = fun(56, &n);等价。

函数名或指向函数的指针变量作为实参

函数名或指向函数的指针变量可以作为实参传递给函数。这时,对应的形参应当是类型相同的指针变量

例 2 通过给tran函数传送不同的参数名,求tan x和cot x的值。

#include <stdio.h>
#include <math.h>

double tran(double (*)(double), double (*)(double), double);    //函数说明语句

int main(void)
{
    double y, v;
    
    v = 60 * 3.1416 / 180.0;
    y = tran(sin, cos, v);              //第一次调用
    printf("tan (60) = %10.6f\n", y);
    
    y = tran(cos, sin, v);              //第二次调用
    printf("cot (60) = %10.6f\n", y);
    
    return 0;
}

double tran(double (*f1)(double), double (*f2)(double), double x)
{
    return (*f1)(x) / (*f2)(x);
}

函数tran有三个形参f1,f2,x。其中f1和f2是两个指向函数的指针变量,它们所指函数的返回值必须是double类型,所指函数有一个double类型的形参。第三形参x是double类型的简单变量。

v的值是60°角的弧度。

在第一次调用中,把库函数sin的地址传送给指针变量f1,把库函数cos的地址传送给指针变量f2,tran函数的返回值是sin(x) / cos(x)。

在第二次调用中,把库函数cos的地址传送给指针变量f1,把库函数sin的地址传送给指针变量f2,tran函数的返回值是cos(x) / sin(x)。

函数的递归调用

函数的递归调用指的是:函数可以直接或间接地调用自己。前者称简单递归,后者称间接递归

一个问题要采用递归方法来解决,必须符合以下三个条件:

  1. 可以把要解的问题转化为一个新的问题,这个新的问题的解法与原来的解法相同,只是所处理的对象有规律地递增或递减。
  2. 可以应用这个转化过程使问题得到解决。
  3. 必须要有一个明确的结束递归的条件。

例 3 用递归的方法求n!

#include <stdio.h>

int fac(int n)
{
    int t;
    
    if(n == 1 || n ==0)
        return 1;
    else
    {
        t = n * fac(n - 1);
        return t;
    }
}

int main(void)
{
    int m, y;
    
    printf("Enter m:");
    scanf("%d", &m);
    
    if(m < 0)
        printf("Input data error!\n");
    else
    {
        y = fac(m);
        printf("\n%d! = %d\n", m, y);
    }
    
    return 0;
}

当函数自己调用自己时,系统将自动把函数中当前的变量和形参暂时保存起来,在新一轮的调用过程中,系统将为该次调用的函数所用到的变量和形参开辟另外的存储单元。因此,递归调用的层次越多,同名变量所占用的存储单元也就越多。

注意:函数的递归调用通常会降低程序的运行效率。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容

  • 原文地址:C语言函数调用栈(一)C语言函数调用栈(二) 0 引言 程序的执行过程可看作连续的函数调用。当一个函数执...
    小猪啊呜阅读 4,585评论 1 19
  • 指针是C语言中广泛使用的一种数据类型。 运用指针编程是C语言最主要的风格之一。利用指针变量可以表示各种数据结构; ...
    朱森阅读 3,423评论 3 44
  • 参考资料:《全国计算机等级考试二级教程——C语言程序设计》《21天学通C语言》 库函数 函数是什么 函数是已命名的...
    NoelleMu阅读 1,130评论 0 0
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy阅读 9,504评论 1 51
  • 回公司途中,颠簸的公交车上,目睹天色渐暗,华灯初上。声哑唇干的,没人有意愿说点什么。 只有师傅仍鼓励着大家,谁谁今...
    中间树子阅读 293评论 0 0