时间:2022-10-09 17:32:10 | 浏览:342
一、函数概述
1、首先什么是函数?
函数是用于完成特定任务的程序代码的自包含单元。
2、为什么使用函数?
第一、函数的使用可以身故重复代码的编写。第二、函数使得程序更加模块化,有利于程序的阅读修改和完善。
3、main函数原型
int main (int argc, char * argv[], char * envp[]) {....}
第一个参数:命令行参数的个数
第二个参数:命令行参数的地址信息
第三个参数:环境表的首地址
参数argc表示输入参数的个数(含命令名),如果有命令行参数,argc应不小于1;argv表示传入的参数的字符串,是一个字符串数组,argv[0]表示命令名,argv[1]指向第一个命令行参数;至于第三个参数env,它与全局变量environ相比也没有带来更多益处,所以POSIX.1也规定应使用environ而不使用第三个参数。通常用getenv和putenv函数来存取特定的环境变量,而不是直接使用environ变量。例如:
//main函数原型的使用
#include <stdio.h>
int main(int argc,char* argv[],char* envp[])
{
printf("argc=%d ",argc);
int i=0;
for(i=0;i<argc;i++)
{
printf("感谢%s ",argv[i]);
}
//声明全局变量
extern char** environ;
printf("environ=%p,envp=%p ",environ,envp);//直接访问环境表
return 0;
}
输出结果为:
argc=1
再如:
命令行为:myprogram c:a.txt c:.txt
则:argc==3
argv[0]=="myprogram"
argv[1]=="c:a.txt"
argv[2]=="c:.txt"
再再如:
#include <stdio.h>
int main (int argc, char *argv[])
{
int count;
printf ("The command line has %d arguments: ", argc - 1);
for (count = 1; count < argc; count++)
printf ("%d: %s ", count, argv[count]);
printf (" ");
return 0;
}
输出结果:
tarena@ubuntu:~/project/C$ ./a.out I LOVE YOU
The command line has 3 arguments:
1: I
2: LOVE
3: YOU
每个C程序都必须有一个 main 函数,因为它是程序执行的起点。关键字 int 表示函数返回一个整型值,关键字 void 表示函数不接受任何参数。main 函数的函数体包括左花括号和与之匹配的右花括号之间的任何内容。
注意:如果没有写明返回值,一般默认为 int 类型。
main (void)
{
...
return 0;
}
二、函数声明和定义 可以加下小编的群466572167,可以交流学习,也有资料下载
1、函数声明
在任何程序在使用函数之前都需要声明该函数的类型。
例如:int imax (int a, int b);
第一个int指的是函数类型;位于圆括号内的两个int表明该函数的形式参数为int类型。分号的作用表示该语句是进行函数声明而不是函数定义。
在函数原型中可以根据自己的喜好省略变量名。
int imax (int , int);
需要注意的是这些变量名只是虚设的名字,他们不必和函数定义中使用的变量名想匹配。使用这种函数原型信息,编译器就可以检查函数调用语句是否和其原型声明一致。比如检查参数个数是否正确,参数类型是否匹配。将声明语句放置在main ()之前和之内两种方式都是正确的。需要重点注意的是函数声明要在使用函数之前进行。当在main之前函数定义的话,就不需要声明语句了。
#include <stdio.h>
int imin (int, int);
int main (void)
{
int inim (int, int);
}
2、隐式声明
如果被调用函数写在调用函数后面则编译器会猜测被调用函数的格式,这叫做函数的隐式声明。隐式声明可以和实际情况不一致这时就会出错,可以把被调用函数的声明单独写在文件开头,这叫做函数的显示声明。除了主函数以外的所有函数都应该进行显示声明,因为主函数永远不是被调用函数。如果main()之后又函数定义,main()之前却没有函数声明的话,编译的时候会出现隐式声明报错。
3、头文件的使用
如果把main ()函数放在第一个文件中吧自定义哈拿书放在第二个文件中实现,那么第一个文件仍需要使用函数原型。如果把函数原型放在一个头文件中,就不必每次使用这些函数时输入其原型声明了。
#ifndef __02READ_H__
#define __02READ_H__
extern int num; //主函数全局变量写在了头文件里且要加extern关键字
int read(char, int); //函数声明
#define PI 3.14
#endif
4、函数定义
函数声明只是将函数类型告诉编译器,而函数定义部分则是函数的实际实现代码。之所以使用函数原型,是为了在编译器编译第一个调用函数的语句之前想其表明该函数的使用方法。因此,可以在首次调用某函数之前对该函授进行完整的定义。这样函数定义部分就和函数原型有着相同的作用。通常对较小的函数会这样做:
//下面既是一个函数的定义,也是它的原型
#include <stdio.h>
int imax (int a, int b)
{
return a > b ? a : b;
}
int main (void)
{
int x, z;
scanf ("%d", &x);
z = imax (x, 50);
printf ("%d ", z);
return 0;
}
三、函数形参与实参 可以加下小编的群466572167,可以交流学习,也有资料下载
1、形式参数
函数定义为下面的函数:
void show (char ch, int num)
这行代码通知编译器show()使用名为ch和num的两个参数,并且这两个参数的类型分别为char和int。变量ch和num被称为形式参数。
注意:ANSI C形式要求在每个变量前声明其类型。也就是说,不能像通常变量声明那样使用变量列表声明同一类型的变量。如下所示:
void dibs (int x, y, z) /*不正确的函数头*/
void dibs (int x, int y, int z) /*正确的函数头*/
2、实际参数
函数调用中,通常使用实际参数对ch和num赋值,如:
show (SPACE, 12);
形式参数是被调函数中的变量,而实际参数是调用函数分配给被调用函数变量的特定数值。实际参数可以是常量、变量或一个复杂的表达式。但是无论何种形式的实际参数,执行时首先要计算其值,然后将该值复制给被调用函数中相应的形式参数。
3、无参数
void dibs (void);
为了表示一个函数确实不使用参数,需要在圆括号内加入void关键字。
四、递归函数
1、递归介绍
C允许一个函数条用其本身,这种调用过程被称为递归。
递归与循环比较:
采用递归函数解决问题的思路叫递归
采用循环解决同样问题的思路叫递推
递归一般可以代替循环语句使用。有些情况下使用循环语句比较好,而有些时候使用递归更有效。递归方法虽然使用程序结构优美,但其执行效率却没有循环语句高。一般来说,选择循环更好一些。首先,因为每次递归调用都拥有自己的变量集合,所以就需要占用较多的内存;每次递归调用需要把心的变量集合存储在堆栈中。其次,由于进行每次函数调用需要花费一定的时间,所以递归的执行速度较慢。
//示例一
#include <stdio.h>
void show (int);
int main (void)
{
show (1);
return 0;
}
void show (int n)
{
printf ("Level %d: n location %p ", n, &n);
if (n < 4)
show (n + 1);
printf ("Level %d: n location %p ", n, &n);
}
执行结果如下:
Level 1: n location 0xbf8bf680
Level 2: n location 0xbf8bf660
Level 3: n location 0xbf8bf640
Level 4: n location 0xbf8bf620
Level 4: n location 0xbf8bf620
Level 3: n location 0xbf8bf640
Level 2: n location 0xbf8bf660
Level 1: n location 0xbf8bf680
//示例二
#include <stdio.h>
void print (int num)
{
if (num == 1)
{
printf ("1 ");
return ;
}
printf ("%d ", num);
print (num -1);
}
int main (void)
{
print (10);
return 0;
}
输出结果:
10
9
8
7
6
5
4
3
2
1
2、递归的基本原理
第一:每一级的函数调用都有自己的变量。
第二:每一次函数调用都会有一次返回。
第三:递归函数中,位于递归调用前的语句和各级被调用函数具有相同的执行顺序。
第四:递归函数中,位于递归调用后的语句的执行顺序和各个被调用函数的顺序相反。
第五:虽然每一级递归都有自己的变量,但是函数代码并不会得到复制。
最后:递归函数中必须包含可以终止递归调用的语句。
3、递归的优缺点
其优点在于为某些变成问题提供了最简单的解决方法,而缺点是一些递归算法会很快耗尽计算机的内存资源。同时,使用递归的程序难于阅读和维护。
五、指针函数和函数指针 可以加下小编的群466572167,可以交流学习,也有资料下载
指针函数:返回指向char的指针的函数,例如:char * fump ( );
函数指针:指向返回类型char的函数指针,例如:char (* frump) ( );
这里需要明白一个符号之间优先级的问题,"( )"的优先级比"*"要高。
再考虑一个,char (* flump[3]) ( );
由3个指针组成的数组,每个指针指向返回类型为 char 的函数。
小编就把自己对C语言里面函数的了解,总结了一下,写了个大概,对于刚接触C语言知识的各位,可以看一下这篇文章,希望对大家有所帮助吧。
俗话说,“百中难挑一,万里难成对”说的就是文玩核桃。因此,想要玩一对儿好核桃,配对儿也就成了不可忽视的问题。想要配出品相完美的核桃需要有两个步骤,即分别挑选和组合成对儿。分别挑选是指要挑选出适合盘玩的核桃,这既是配对的前提,也是盘出好核桃的
盘玩核桃,好多玩友只想着上手就想核桃变漂亮,殊不知文玩核桃变漂亮要经历以下4个阶段,今天小编给大家分享一下,希望能帮到您。1、 轻上色阶段包浆级别:★★有核包浆初养成,还得继续多盘刷!!每个缝隙、每个角落,都要周到的关照!2、 变红润阶段包
乾隆爷当年这样称赞核桃“掌上悬日月。周身气血涌,何年是白头”,虽然这首诗屌丝了一些,但是还是能完整的表达乾隆皇帝对核桃的珍爱之情。远的不说,咱说近的,文玩爱好者大多都是从盘玩核桃开始自己的文玩生涯,怀揣着梦想有一天手里盘着一对儿包浆厚重、玉
何为文玩,一种解释为文人的玩物,那文玩葫芦呢就是可以当做文玩的葫芦。那什么样的葫芦才可以当做文玩葫芦呢?哪样的葫芦可以卖个好价钱呢?1. 尺寸小 一般的文玩葫芦高度在10厘米以内,且越小越稀有珍贵,3厘米以下的本地葫芦可以称之为“草里金”这
国庆长假结束的第一天汽车界就被一则爆料震惊,竟然是奇瑞缺钱,要“被”收购,最后一些自媒体更为干脆,涉及整个奇瑞,殊不知他们眼中所及的“奇瑞”其实真实意义上而言只能代表奇瑞汽车,也就是奇瑞汽车股份有限公司,而非整个“奇瑞”板块,很多人能够知晓
古典红木家具在我国历史中充当着尤为重要的角色,是承载我国古典艺术文化的瑰宝。古时,红木家具可谓是王公贵族或文人雅士的专属,时光荏苒,红木家具传承至今,成为我国历史文化重要载体之一。大红酸枝明式圆台大红酸枝明式官帽椅国泰民安,由于人们的生活水
暑期是近视高发期!眼科医生带你了解孩子近视的10个真相 | 暑期安全公开课⑥暑假以来,在眼科医院就诊患者中,有不少是家长带着孩子前来矫正视力的。假期,孩子们多了放松娱乐的时光,但稍不注意近视问题也会悄悄来到孩子身旁。该如何预防孩子视力下滑?
【近视能够治愈吗?这5大细节你需要了解 】近视的低龄化和持续的高患病率已成为社会普遍关注的问题,首份《义务教育质量监测报告》指出,目前学生视力不良问题突出,四年级、八年级学生视力不良检出率分别达36.5%和65.3%。戳图,常州市第一人民医
人民网北京6月5日电 每年的6月6日是全国爱眼日,眼睛是人类感官中最重要的器官之一,不当的用眼习惯会导致眼部疾病,危害身体健康。新冠肺炎疫情以来,儿童青少年使用电子产品增多、户外活动减少,增加了近视发生的风险。人民网“求真”栏目在第二十五届
创意图片/新京报记者 王远征名医面对面王伟明 北京中医药大学眼科学博士后,东城中医医院副主任医师,运用传统中医“洗、蒸、熏、灸、点眼、按跷、眼针”,外敷内服增视明目中药,形成一整套应用中医“六术”全息针灸疗法。擅长治疗青少年近视、弱视、斜视