一、函数基础知识

1、函数的声明

函数只能定义一次,但可以声明多次。建议在头文件中声明而在源文件定义。函数的声明和函数的定义非常类似,唯一的区别是函数的声明无须函数体,用一个分号替代即可。

2、函数的定义

函数包括以下部分:返回类型、函数名字、由0个或多个形参组成的列表以及函数体。

returntype  functionname (type parameter1,type parameter2…) {……}

函数的形参列表:函数的形参列表可以为空,但是不能省略。void f1()、voidf2(void)

3、形参的基础知识

形参和实参:实参是形参的初始值。第一个实参初始化第一个形参,第n个实参初始化第n个形参。

局部变量:形参和函数体内部定义的变量统称为局部变量,仅在函数的作用域内可见。

自动对象:把只存在于块执行期间的对象称为自动对象。形参是一种自动对象,所以函数一旦结束,形参也就被销毁。

局部静态变量:有时有必要令局部变量的生命周期贯穿函数调用及之后的时间。可以将局部变量定义成static从而获得这样的对象。局部静态对象在程序的执行路径第一次经过对象定义语句时初始化,并且直到程序终止才被销毁,在此期间即使对像所在的函数结束执行也不会对它有影响。

二、参数传递

1、函数传参的三种方式:传值传递、地址传递、引用传递

(1)传值传递

(1)传值传递即将实参的值拷贝给形参。形参和实参是两个相互独立的对象,各占一个独立的存储空间。

(2)形参的存储空间是函数被调用时才分配的,调用开始,系统为形参开辟一个临时的存储区,然后将各实参传递给形参,这是形参就得到了实参的值。

示例代码:

#include

void swap1(int x, inty)//定义中的x,y变量是swap函数的两个形参

{

int tmp;

tmp = x;

x = y;

y = tmp;

printf("x=%d,y=%d\n", x, y);

}

int main()

{

int a = 2;

int b = 3;

swap1(a, b);//a,b变量为swap函数的实际参数

printf("a=%d,b=%d", a, b);

return 0;

}

输出结果为:x=3,y=2; a=2,b=3

代码分析:a虽然赋值给x,但是a的值并没有改变,对x的任何修改都不会改变a的值。函数是通过赋值把a,b赋给x,y,这是一个隐含操作,我们不能把它显式的写出来,进行函数中变量的值进行交换时只是形参x,y的交换,并没有对实参进行真正交换,所以a,b值不变。

(2)地址传递

因为指针使我们可以间接地访问它所指的对象,所以通过指针可以修改它所指对象的值。

地址传递与值传递的不同在于,它把实参的存储地址传送给形参,使得形参指针和实参指针指向同一块地址。因此,被调用函数中对形参指针所指向的地址中内容的任何改变都会影响到实参。

示例代码:

void swap2(int *px, int*py)

{

int tmp;

tmp = *px;

*px = *py;

*py = tmp;

printf("px=%d,py=%d\n", *px, *py);

}

int main()

{

int a = 2;

int b = 3;

swap2(&a, &b);/*调用了swap函数,同样也有隐含动作px=&a;py=&b;*/

printf("a=%d,b=%d", a, b);

return 0;

}

运行结果为px=3,py=2;a=3,b=2;

代码分析:有了两行隐含赋值操作,我们可以清晰的看出指针*px,*py是对变量a,b的值操作。函数里面对a和b的值进行了交换。这就是传址。

(3)引用传递

引用传递是以引用为参数,则既可以使得对形参的任何操作都能改变相应数据,又使函数调用方便。引用传递是在形参调用前加入引用运算符“&”。引用为实参的别名,和实参是同一个变量,则他们的值也相同,该引用改变则它的实参也改变。

代码示例:

#include

void  swap3(int &x,int &y)

{

int tmp = x;

x = y;

y = tmp;

printf("x=%d,y=%d\n", x, y);

}

int main()

{

int a = 2;

int b = 3;

swap3(a, b);//调用方式与传值一样

printf("a=%d,b=%d", a, b);

system("pause");

return 0;

}

输出结果:x=3,y=2; a=3,b=2;

代码分析:我们看到该代码只与传值中swap函数定义不同,swap3中参数都加了取地址符号&,有了这个函数会将a,b分别替代了x,y,这样函数里面操作就是a,b本身了。

2、结论

(1)除非实参是具体数值(5等)或者实参和形参是相同的名字外,避免使用传值传递。

(2)当某种类型不支持拷贝时,函数只能通过引用形参访问该类型的对象。

(3) 一个函数只能返回一个值,然而有时候函数需要同时返回多个值,引用形参为我们一次返回多个结果提供了有效的途径。

三、数组形参

1、数组的两个特殊性质:

①不允许拷贝数组(arry1=arry2):因为不能拷贝数组,所以无法以值传递的方式使用数组参数。

②使用数组时会将其转换成指针:因为数组会被转换成指针,所以当为函数传递一个数组时,实际传递的是只想数组首元素的指针。

2、数组数据的传送

要确定一个一维数组只需要知道:一个是数组的首地址,另一个是数组的长度,这样就可以唯一地确定一个一维数组。因此,要想通过实参和形参将一个数组从主调函数传到被调函数,那么只需要传递这两个信息即可。

因为数组是连续存放的,只要知道数组的首地址和数组的长度就能找到这个数组中所有的元素。对于一维数组来说,其数组名就表示一维数组的首地址。所以只需要传递数组名和数组长度这两个参数就可以将数组从主调函数传入被调函数中。

当数组名作为函数的实参时,形参列表中也应定义相应的数组(或用指针变量),且定义数组的类型必须与实参数组的类型一致,如果不一致就会出错。但形参中定义的数组无须指定数组的长度,而是再定义一个参数用于传递数组的长度。所以在传递实参的时候,数组名和数组长度也只能用两个参数分开传递,而不能写在一起。因为即使写在一起,系统在编译时也只是检查数组名,并不会检查数组长度。所以数组长度要额外定义一个变量进行传递。

当将数组从一个函数传到另一个函数中时,并不是将数组中所有的元素一个一个传过来(那样效率就太低了)。而是将能够唯一确定一个数组的信息传过来,即数组名(数组首地址)和数组长度。此时主调函数和被调函数操作的就是同一个数组。

数组名就是数组的首地址。因此在数组名作函数参数时所进行的传送只是地址的传送,也就是说把实参数组的首地址赋予形参数组名。形参数组名取得该首地址之后,也就等于有了实在的数组。实际上是形参数组和实参数组为同一数组,共同拥有一段内存空间。

当用数组名作函数参数时,情况则不同。由于实际上形参和实参为同一数组,因此当形参数组发生变化时,实参数组也随之变化。当然这种情况不能理解为发生了“双向”的值传递。但从实际情况来看,调用函数之后实参数组的值将由于形参数组值的变化而变化。

一般来数参数的传递是值传递,也就是说实参传给形参,形参发生改变时实参并不会改变,(单向)。但是数组在传递的时候是地址传递,只要形参发生了变化,实参也会发生变化(“双向”)。

3、管理指针形参

因为数组是以指针的形式传递给函数的,所以开始函数并不知道数组的确切大小,调用者应该为此提供一些额外的信息。管理指针形参有三种常用技术:

(1)使用标记指定数组长度

指要求数组本身包含一个结束字符。这种方法适用于有明显结束标记且该标记不会与普通数据混淆的情况,倒是对像int这样所有取值都是合法值的数据就不太有效了。

void printf(char *cp)

{

if(cp)         /*若数组不是一个空指针*/

while(*cp)   /*只要指针所指的字符不是空字符*/

cout<

}

(2)使用标准库规范

指传递指向数组首元素和尾后元素的指针。为了调用这个函数,需要定义两个指针:一个指向要输出的首元素,另一个指向尾元素的下一位置。

(3)显式传递一个表示数组大小的形参

指专门定义一个表示数组大小的形参。

# include

int AddArray(intarray[], int n);  //函数声明

int main(void)

{

inta[] = {1, 2, 3, 4, 5, 6, 7, 8};

/*数组所占内存总大小除以该数组中一个元素所占内存的大小, 从而得到数组元素的个数*/

int size = sizeof(a) / sizeof(a[0]);

printf("sum = %d\n", AddArray(a,size));

return 0;

}

int AddArray(intarray[], int n)  //形参数组中不需要写长度

{

int i, sum = 0;

for (i=0; i

{

sum += array[ i];

[ i]

}

return sum;

}

输出结果:sum=36

int test1(int *p)

{

for(int i=0;i<5;i++)

{

printf("%d",p[ i]); //我们在这里还可以用)*(p+i)来输出数组中的值

[ i]

}

}

int test2(int a[])

{

for(int i=0;i<5;i++)

{

printf("%d",a[ i]);

[ i]

}

}

int main()

{

int a[5] = {1,2,3,4,5},*p;

p = a;

test1(p);

test2(a);

}

#include

floataver(float a[5]){

int i;

float av,s=a[0];

for(i=1;i<5;i++)

s=s+a[ i];

[ i]

av=s/5;

return av;

}

intmain(void){

float sco[5],av;

int i;

printf("\ninput 5 scores:\n");

for(i=0;i<5;i++)

scanf("%f",&sco[ i]);

[ i]

av=aver(sco);

printf("average score is%5.2f",av);

return 0;

}

在函数形参表中,允许不给出形参数组的长度,或用一个变量来表示数组元素的个数。例如,可以写为:

void nzp(int a[])

或写为

void nzp( int a[], int n )

其中形参数组a没有给出长度,而由n值动态地表示数组的长度。n的值由主调函数的实参进行传送。

4、传递多维数组

多维数组也可以作为函数的参数。在函数定义时对形参数组可以指定每一维的长度,也可省去第一维的长度。因此,以下写法都是合法的:

int MA(int a[3][10]) 或 int MA(int a[][10])。

因为多维数组是数组的数组,所以首元素本身就是一个数组,指针就是一个指向数组的指针。数组第二维(以及后面所有维度)的大小都是数组类型的一部分,不能省略。

Void fun1( int (*matrix)[10], introwsize ) {……}

Void fun1( int matrix[][10], introwsize ) {……}

灵活的去定位到某一行某一列:

void test2(int  m,int n,int **p)

{

//m,n是行和列,

for(int i = 0; i < m; i++)

{

for(int j = 0; j < n; j++)

{

printf("%d ",*((int*)p+n*i+j));

}

}

}

int main()

{

int a[5][5],i,j;

for(i = 0; i < 5; i++)

{

for(j = 0; j < 5; j++)

{

a[ i][j] = i*5 + (j +1);

[ i]

}

}

test2(5,5,(int **)a);

return 0;

}

或者:

#include

void test2(int  m,int n,int *p)

{

//m,n是行和列,

for(int i = 0; i

{

for(int j = 0; j < n; j++)

{

printf("%d ",*(p+n*i+j));

}

}

}

void main()

{

int a[5][5],i,j;

for(i = 0; i <5; i++)

{

for(j = 0; j < 5; j++)

{

a[ i][j] = i*5 + (j +1);

[ i]

}

}

test2(5,5,(int *)a);

}

aver函数C语言怎么用,C语言函数使用相关推荐

  1. c语言中aver是什么意思_嵌入式C语言基础编程—5年程序员给你讲函数,你真的懂函数吗?...

    本文主要讲述的内容: 1函数概述 2函数定义的一般形式 3函数的参数和函数的值 3.1形式参数和实际参数 3.2函数的返回值 4函数的调用 4.1函数调用的一般形式 4.2函数调用的方式 4.3被调用 ...

  2. c语言算法6,c语言6函数和算法.ppt

    c语言6函数和算法创新 近半个月目标 学会使用函数进行模块化程序设计 学会调试由多个函数(包含库函数)组成的程序 主要内容 模块化程序设计思想 函数定义和函数调用.函数原型(函数声明) 函数的参数和返 ...

  3. C语言中fun的功能是将字符串,c语言程序设计请编写一个函数fun,它的功能是:将ss所指字符串中所.,c语言程序设计题 请编写一个函数fun,它的功能是:将ss所...

    计算机二级C语言上机南开100题--1 1: 第1题 m个人的成绩存放在score数组中,请编写函数fun,它的功能是:将低于平均分的人作为函数值返回,将低于平均分的分数放在below所指定的函数中. ...

  4. [编程神域 C语言浮游塔 第④期] 函数的基本知识

     前言 通过上一期的学习,我们知晓了数组及其不同的使用方法. 本期学习的是C语言中的函数,可类比为java中的方法. 函数是构成C程序的基本单元,可以说C程序通常由若干函数组成,它包括函数头和函数体. ...

  5. C语言小知识:typedef\函数模板\

    (1)typedef用法: typedef为C语言的关键字,作用是为一种数据类型定义一个新名字.这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(struct等).在编程中使用t ...

  6. C语言中连续调用rand函数,返回值不变

    C语言中连续调用rand函数,返回值不变 最近用C语言随机函数编程发现了一个奇怪的现象: 简易版代码: #include<stdio.h> #include<stdlib.h> ...

  7. python中函数包括标准库函数吗_Python语言和标准库(第二章:函数)

    a-如何创建函数. b-给出一些指导原则,帮助思考如何创建和组织程序以使用函数. c-如何编写函数,使随后可以询问它们的工作方式和实现的功能. 2.1将程序放在单独的文件里 为了更加方便,从现在开始, ...

  8. R语言使用R基础安装中的glm函数构建乳腺癌二分类预测逻辑回归模型、分类预测器(分类变量)被自动替换为一组虚拟编码变量、summary函数查看检查模型、使用table函数计算混淆矩阵评估分类模型性能

    R语言使用R基础安装中的glm函数构建乳腺癌二分类预测逻辑回归模型(Logistic regression).分类预测器(分类变量)被自动替换为一组虚拟编码变量.summary函数查看检查模型.使用t ...

  9. R语言使用ggplot2包geom_jitter()函数绘制分组(strip plot,一维散点图)带状图(添加箱图、带缺口的小提琴图、小提琴图)实战

    R语言使用ggplot2包geom_jitter()函数绘制分组(strip plot,一维散点图)带状图(添加箱图.带缺口的小提琴图.小提琴图)实战 目录 R语言使用ggplot2包geom_jit ...

最新文章

  1. R语言使用pwr包的pwr.t.test函数对分组样本数相同的t检验进行效用分析(power analysis)、在已知效应量(effect size)、显著性水平、样本量的情况下计算假设检验的效用值
  2. PHP的抽象类的一段简单代码示例
  3. C语言 · 求存款
  4. 深度探索C++ 对象模型(7)-Data member的布局(虚继承)
  5. ConcurrentHashMap的源码分析-addCount
  6. mootools框架【十】-mootools深层探讨
  7. [Linux] Ubuntu下的文件比较工具--meld
  8. uban系统如何安装java_Ubuntu系统下安装Java并配置环境
  9. UltraEdit for Mac
  10. 华三ap设置无线服务器,H3C无线控制器实现Remote AP功能典型配置举例(V7)
  11. 百度 PaddlePaddle开源视频分类模型Attention Cluster,曾夺挑战赛冠军
  12. 锐捷长ping_锐捷实战系列(二) Wireshark抓包分析Ping过程
  13. TextStyleOpts:文字样式配置项
  14. GO+Selenium批量关注各大网站实战 1 (基础+demo)
  15. 双卡 一卡通话 卡2丢网 ---注册状态 VOICE_REGISTRATION_STATE
  16. 证券考试和基金考试有什么区别?
  17. 计算机领域怎么研究区块链,计算机行业深度研究:跨链技术,区块链大航海时代的基石...
  18. 一本建立程序员(其它从业者)世界观、价值观和人生观的书——《黑客与画家》读书笔记
  19. 用css实现垂直水平居中的几种方法
  20. js 数组根据特定规则排序

热门文章

  1. IDEA创建Maven Web 项目
  2. C/C++ Memory Layout
  3. shell判断文件,目录是否存在或者具有权限 (转载)
  4. SQLGrammarException错误
  5. 【RMAN】正确删除归档日志的方式
  6. 3个概念,入门 Vue 组件开发
  7. openssl内存分配,查看内存泄露
  8. UITableView长按拖动排序(支持不同行高,不同section间交换)
  9. 使用vmware12安装Ubuntu 遇到的两个问题和解决
  10. 女生做程序员压力大吗?