概念
“函数”是从英文function翻译过来的,其实,function在英文中的意思即是“函数”,也是“功能”。从本质意义上来说,函数就是用来完成一定功能的。这样对函数的概念就很好理解了,所谓函数名就是给该功能起个名字,如果该功能是用来实现数学运算的,就是数学函数。
函数的写法
返回类型 函数名(参数1, 参数2, ... 参数n)//参数可以不写
{
//函数体
....
return 返回类型; //如果返回类型为void 可以没有return.
}
main函数
每个C语言程序至少有一个函数,我们常常用main()函数, 也称之为主函数, 但是C语言的程序的主函数是不是一定叫main呢? 答案当然是否定的, 操作系统在执行main函数之前, 调用了其他代码, 这些代码就有初始化main函数所需的运行环境,而负责初始化main函数的这个函数就称之为入口函数/入口点.而入口函数规定的C程序的主函数就是main, 那么我们当然可以找到这个文件,修改主函数名.
main函数的返回值
main函数的返回值一般有两种写法 1.void main
2.int main
但是这前者最好不要使用, 不仅仅是有些编译器不支持.还因为操作系统对于一个程序的正常或者执行异常都是整型,如果程序返回 0 表示程序正常执行, 如果返回其他整型,执行异常.那么可以说void main
就是一种不恰当的写法. int main的返回值为0或者不为0的程序的执行结果其实都一样,但为什么一定要返回0呢? 举个例子:
//test.c
#include <stdio.h>
int main(){
printf("hello ");
return 0;
}
//test1.c
#include <stdio.h>
int main(){
printf("world!\n");
return 0;
}
执行test 和 test1 &&运算符是指执行成功&&前面的便执行后面的, 如果执行前面失败,后面便不会执行.
panyiwen@god:~/temp$ ./test && ./test1
hello world!
如果我们将第一个test.c的返回值改为return 1;
执行结果:
panyiwen@god:~/temp$ ./test && ./test1
hello panyiwen@god:~/temp$
只输出hello , 没有world和换行.也就是第二个test1.c没有执行.原因便是第一个程序的返回值是1,系统认为该程序没有执行成功.所以不会执行第二个test1
main函数的三种写法(两种)
1.int main(void) //括号中的void可以不写
2.int main(int argc, char *argv[])
3.int main(int argc, char *argv[], char *envp[]) //不建议使用, 因为第三个参数只是类unix系统的拓展
其实也就是main函数中可以不写参数, 写两个参数, 写三个参数. 因为是参数,所以名称可以自己取,也可以就用上述名称.
三个参数
int argc
整型参数, argc = 1+输入的参数个数, 系统自动赋值, 无需我们写, 1 为程序的名称.char *argv[]
字符串数组, argv[0] 表示程序的名称, argv[1]~argv[argc-1]代表我们传入的参数.char *envp[]
字符串数组, 表示系统的环境变量
例子:
1 | #include <stdio.h> |
我们执行这段程序, 并输入参数hello world, 部分输出结果, 因为系统环境变量太多.
panyiwen@god:~/temp$ ./test hello world
3
./test hello world
XDG_VTNR=7 XDG_SESSION_ID=c2 CLUTTER_IM_MODULE=xim XDG_GREETER_DATA_DIR=/var/lib/lightdm-data/panyiwen GPG_AGENT_INFO=/home/panyiwen/.gnupg/S.gpg-agent:0:1 SHELL=/bin/bash TERM=xterm-256color ...
我们可以看到, argc = 3 执行的程序名称+两个参数 argv = {“./test”, “hello”, “world”}; 而envp则全是系统环境变量key=value的字符串. 那么我们知道系统环境变量有什么用? 我们可以得到环境变量配置的一些参数来完成我们需要的功能,但是不建议推荐使用第三个参数传入,因为拓展性不强, 我们可以通过C语言的#include <stdlib.h>
库中的函数来得到和设置删除系统环境变量.这样在不同系统上的使用方式就是一致的.
库函数
C语言库函数是把自定义函数放到库里,是别人把一些常用到的函数编完放到一个文件里,供程序员使用。程序员用的时候把它所在的文件名用#include<>加到里面就可以了(尖括号内填写文件名),例如
#include <math.h>
。
库函数也就是一些程序员大牛们,他们将一些我们常用的函数,写到文件里面供我们调用,每次计算机语言的更新,除了一些语法的更新外,很多也是加入一些别的优秀的代码文件加入库中. 说到库函数,我们就不得不提#include <stdio.h>
我们平常写的几乎所有的C程序的开头都会加上这么一句,标准输入输出.那么我们就来介绍以下stdio.h.
stdio.h
stdio 就是指 “standard input & output”(标准输入输出) 所以,源代码中如用到标准输入输出函数时,就要包含这个头文件!
引用方法: #include <stdio.h>
stdio.h所包含的函数: 文件访问: fopen,freopen,fflush,fclose 二进制输入/输出: fread, fwrite 非格式化输入/输出: fgetc/getc, fputc/putc, ungetc, fgets ,fputs 格式化输入/输出: scanf/fscanf/sscanf ,printf/fprintf/sprintf, perror 文件定位: ftell, fseek, fgetpos ,fsetpos, rewind 错误处理: feof, ferror 文件操作: remove, rename, tmpfile
大名鼎鼎的EOF 也是宏定义在stdio.h中, 一般编译器定义是: #define EOF -1
, 我们常用的scanf, printf 函数都是写在stdio.h中.
scanf函数和printf函数:
用 法: int scanf(char *format[,argument,…]); 用 法: int printf(“<格式化字符串>”, <参量表>);
我们知道scanf是格式化输入, 调用此函数,我们在计算机的键盘中输入的字符串会传化为相对应的格式,储存到变量中, 并返回一个整数,代表成功输入了多少个. printf是格式化输出, 输出内容到显示器(终端) 返回值是输出字符的个数,若出错,则返回负数。 . 例子:
int num = scanf("%f %d", &a, &b);
printf("a=%f, b=%d, num = %d\n", a, b, num);
分析:上面的例子,如果我们正常输入11.2 2
,那么函数就会返回一个2表示我们输入成功输出a=11.200000, b=2, num=2
, 如果我们输入11.2 a
那么就会将11.2 赋值给 a, 但是’a’无法赋值给b, 输入就会失败, 输出a=11.200000, b=517694128, num=1
b被随机赋予了一个值, 成功输入一个.如果是a 11
那么返回值就是0了,a,b都会被随机赋值. 小知识: 我们知道一个变量是要在内存中开辟一段内存的, 变量储存的值是储存在内存中, &为取地址符,我们要存值, 必须知道变量的地址. 我们平时用的a 其实是 &a 先取出地址再得到内存中的值, 为了方便将&省略. 但是如果用的多的人就会发现scanf有一些很神奇的事情发生,举几个例子:
scanf("%d %lf", &a, &b);
scanf("%s", ch);
scanf("%d%c",&a, &c);
我们对其输出, 第一个我们输入11.234 12.3
,结果: a=11 b=0.234000
第二个我们输入Hello World !!!
, 结果: Hello
第三个我们输入16 c
, 结果:a=16 c=' '
我们其实明白scanf输入浮点型给整型会被强制转换, 字符串%s是不能接受空格的, 如果我们没有规定分隔符是什么,一般默认是空格, 但是输入的空格会被%c接收,所以c=’ ‘,等等很多有意思的点, 那么我们就来看看这个理由吧.先引入点知识点:
stdin, stdout, stderr的简单介绍:
1.stdin, 标准输入流: 通常是键盘输入. 2.stdout, 标准输出流: 输出到屏幕. 3.stderr, 标准错误流: 无缓冲.输出到屏幕. 一般是错误信息. 全缓冲: 直到文件结束或者手动清空缓存,才清空缓冲. 行缓冲: 遇到回车或者换行, 或者文件结束, 清空缓冲
ISO C规定: 当且仅当stdin和stdout不指向交互式设备时,他们才是全缓冲。 stderr决不会是全缓冲。 Linux系统默认: stderr是不带缓冲的。 若流指向终端设备,则是行缓冲,否则为全缓冲。
所以在c语言中stdin和stdout是行缓冲, 我们的scanf和printf函数就是使用了stdin和stdout, 而stdin和stdout就是写在stdio中的.本质就是系统帮我们打开了两个文件句柄. 我们输入的数据就储存在stdin那个文件中, 输出的数据就存储在stdout文件中, 我们调用scanf和printf就是在文件中取数据, 进行输入和输出. 第一个例子scanf("%d %lf", &a, &b);
我们就是从缓冲区stdin 也就是字符串取出11
赋值给a 取出.234
赋值给b. 所有有关这些奇特的现象就是和stdin和stdout有关. *scanf 也就是 int fscanf(stdin, const char format, [argument…]); 遇到换行或空格结束 *printf 也就是int fprintf( stdout, const char format, [ argument ]…); 其他的库函数也就是大同小异,主要是知道怎么用的就好.
自定义函数
在库函数不满足我们的需求的时候, 我们又不想把所有代码都写在主函数里面, 那样不仅丑,而且可读性,复用性都很差.那么我们就需要自定义函数,来满足我们的需要 写法和main函数一样
返回值类型 函数名(参数1, 参数2 ...)//可不写
{
//函数体
...
return 返回值;
}
举个例子, 比大小, 返回最大值:(虽然库函数中有)
int max(int a, int b){
return a > b ? a : b; //三目运算符 等价与 if(a > b) {return a;} else{ return b;}
}
int main(){
int a = 100, b = 120;
int maxnum;
maxnum = max(a, b); //调用max函数 返回两个数最大的那个
return 0;
}
C语言中需要注意的是函数要么写在执行前面, 要么是需要声明(告诉计算机有这个函数), 要不然找不到. 也就是掉个位置:
int main(){
int a = 100, b = 120;
int maxnum;
int max(int, int); //使用前需要声明有这个函数 只要使用前声明就好,也就是可以写在int main()的上面也可以.
maxnum = max(a, b); //调用max函数 返回两个数最大的那个
return 0;
}
int max(int a, int b){
return a > b ? a : b; //三目运算符 等价与 if(a > b) {return a;} else{ return b;}
}
声明也就是告诉计算机,如果在这之前没找到这个函数没关系,先别报错,我的函数在下面.
友情链接:
http://blog.csdn.net/Crazy_Tengt/article/details/72717144
http://blog.csdn.net/q565220/article/details/49951885