-
类型模板形参
2017-03-31 16:24:521、 模板定义以关键字template 开始,后接模板形参表,模板形参表是用尖括号...非类型形参跟在类型说明符之后声明。类型形参跟在关键字 class 或 typename 之后定义,例如,class T 是名为 T 的类型形参,在这里 class1、 模板定义以关键字template 开始,后接模板形参表,模板形参表是用尖括号括住的一个或多个模板形参的列表,形参之间以逗号分隔。模板形参表不能为空。
2、 模板形参可以是表示类型的类型形参,也可以是表示常量表达式的非类型形参。非类型形参跟在类型说明符之后声明。类型形参跟在关键字 class 或 typename 之后定义,例如,class T 是名为 T 的类型形参,在这里 class 和 typename 没有区别。
3、 使用函数模板时,编译器会推断哪个(或哪些)模板实参绑定到模板形参。一旦编译器确定了实际的模板实参,就称它实例化了函数模板的一个实例。实质上,编译器将确定用什么类型代替每个类型形参,以及用什么值代替每个非类型形参。推导出实际模板实参后,编译器使用实参代替相应的模板形参产生编译该版本的函数。编译器承担了为我们使用的每种类型而编写函数的单调工作。
4、 函数模板可以用与非模板函数一样的方式声明为 inline。说明符放在模板形参表之后、返回类型之前,不能放在关键字 template 之前。
5、 类模板也是模板,因此必须以关键字 template 开头,后接模板形参表。除了模板形参表外,类模板的定义看起来与任意其他类问相似。类模板可以定义数据成员、函数成员和类型成员,也可以使用访问标号控制对成员的访问,还可以定义构造函数和析构函数等等。在类和类成员的定义中,可以使用模板形参作为类型或值的占位符,在使用类时再提供那些类型或值。
6、 与调用函数模板形成对比,使用类模板时,必须为模板形参显式指定实参。
7、 用作模板形参的名字不能在模板内部重用。当然,正如可以重用函数形参名字一样,模板形参的名字也能在不同模板中重用。
8、 同一模板的声明和定义中,模板形参的名字不必相同。每个模板类型形参前面必须带上关键字 class 或 typename,每个非类型形参前面必须带上类型名字,省略关键字或类型说明符是错误的。
9、 除了定义数据成员或函数成员之外,类还可以定义类型成员。如果要在函数模板内部使用这样的类型,必须告诉编译器我们正在使用的名字指的是一个类型。必须显式地这样做,因为编译器(以及程序的读者)不能通过检查得知,由类型形参定义的名字何时是一个类型何时是一个值。
-
C语言中函数传递(实参 形参)
2016-07-06 20:34:19形参:在被调函数形参表中的变量名、数组名,该过程在被调用前,没有为它们分配内存,其作用是说明自变量的类型和形态以及在过程中的作用。 形参可以是 合法变量名,数组名 实参:从主调过程传递给被调用过程的...形参:在被调函数形参表中的变量名、数组名,该过程在被调用前,没有为它们分配内存,其作用是说明自变量的类型和形态以及在过程中的作用。
形参可以是 合法变量名,数组名
实参:从主调过程传递给被调用过程的参数值。实参可以是变量名、数组名、常数或表达式。在过程调用
传递参数时,形参与实参是按位置结合的,形参表和实参表中对应的变量名可以不必相同,但它们的数据类型、参数个数及位置必须一一对应
两者关系:
1. 形参只能是变量,实参可以是常量、变量或表达式。在被定义的函数中,必须指定形参的类型。
2. 实参与形参的个数应一样,类型应一致。字符型和整型可以互相通用。
3. 在调用函数时,如果实参是数组名,则传递给形参的是数组的首地址
4.实参传递给形参是单向传递,形参变量在未出现函数调用时,并不占用内存,只在调用时才占用。调用结束后,将释放内存。执行一个被调用函数时,形参的值如果发生改变,并不会改变主调函数中的实参的值。
5.形参如同公式中的符号,实参就是符号具体的值,在调用过程前必须得到赋值;调用过程就是实现形参与实参的结合,把实参的值通过调用传递给形参,相当于把值代入公式进行计算。C语言中在发生有参函数调用时,实参变量与形参变量之间的数据都是单向的“值传递”方式。包括指针变量和数组名作参数的情况。
C语言要求函数的实参要有确定的值,在函数调用时给形参分配相应的内存单元,同时将实参的“值”赋(复制)给形参,实现数据从实参到形参的传递(‘值传递’方式)。因为是复制,所以在操作副本(形参)过程中不会影响到原本(实参)内容。
首先,作为函数实参的量包括常量、变量和表达式。其中变量又包括简单变量、数组元素、数组名、指针变量等。不同类型变量作参数实现的数据传递方式相同,效果不同。所谓方式相同即都是参数间数据单向的“值传递”,效果不同是指被调函数能否改变主调函数中变量的值。情况一:简单变量或数组元素作为函数参数
数组元素本身属于简单变量,在向形参传递数据时,根据前述规则只需将变量中的“值”复制一份放到形参变量中去操作,此时在被调用函数中操作的对象(形参)与实参并不在同一内存单元,并且在调用结束后形参所占内存单元被释放,因此调用函数不会影响到实参变量的值。同时被调函数也不会影响到主调函数中其他变量的值。
例:1void main()
{
int a=1,
f(int a);
printf(“%d%d”,a,f(a));
}
f(int a)
{
return(++a);
}
例2void main()
{
int a[3]={1,2,3};
f(int a);
printf(“%d%d”,a[0],f(a[0]));
}
f(int a)
{
return(++a);
}情况二:指针变量或数组名作为函数参数
1.指针变量作函数参数
指针变量作实参在调用时仍然符合前述“值传递”规则,将其“值”赋给形参,相当于复制。此时数据在实参与形参间传递仍是单向的,调用函数不会影响实参的“值”(即指针变量中所存地址)。而与简单变量不同的是指针变量复制给形参的“值”本身是一个地址,这个地址为形参访问其所指变量创造了可靠条件。我的理解是,实参是一个抽屉的钥匙,在传参时,实参复制了一把钥匙传给形参。而被调函数拿到钥匙副本后,进行的操作可以分为两类:1、对钥匙本身做了一些操作(对指针本身进行操作);2、通过钥匙对抽屉里的内容进行了一些操作( 对指针所指的变量进行操作);两种操作都不可能影响实参的值(即钥匙原本),却有可能改变实参所指向变量的值(即抽屉里的内容)。
例1void main()
{
void swap(int*p1,int*p2);
int a,b;
int *pointer1,int*pointer2;
scanf(“%d,%d”,&a,&b);
pointer1=&a; pointer2=&b;
if(a -
本周小结
2019-11-29 14:15:47类型名 函数名(形参类型说明表) /*函数首部*/ { /*函数体*/ 说明语句 执行语句 } 其中函数名必须是一个合法的标识符,且不能与其他函数或者变量重名; 类型名指定函数返回值的类型,无返回值的类型应指定为...函数的定义
C语言中函数定义的一般形式为:
类型名 函数名(形参类型说明表) /*函数首部*/ { /*函数体*/ 说明语句 执行语句 }
其中函数名必须是一个合法的标识符,且不能与其他函数或者变量重名;
类型名指定函数返回值的类型,无返回值的类型应指定为void空类型。函数的参数
函数的参数分为形式参数(简称形参)和实际参数(简称实参)。形参是函数名括号中说明的变量称为形式参数;实参是后面调用函数时在被调用处所给出的对应的参数。如
main() { int a=3,b=5; swap(a,b); printf("a=%d,b=%d",a,b); } swap(int x,int y) { int t; t=x; x=y; y=t; }
该程序运行结果为a=3,b=5.
函数的返回值
函数的返回值是指函数被调用、执行完后返回给主调函数的值,其一般表达式为
return 表达式;
功能:将表达式的值带回给主调函数。
函数内可有多条返回语句,但每条语句的返回值只能有一个。如int max(int x,int y) { if(x>y) return x; else return y; }
返回值的类型为函数的类型,如果函数的类型和return中表达式的类型不一致,以函数类型为准,先将表达式的值转换成函数类型后,再返回。
函数的调用
函数调用的一般形式为
函数名 (实参列表);
如
max(a,b);
不管是什么类型的实参,在调用函数时必须有确定的值,且应和形参在类型、顺序上一一对应。对于无参函数,调用时实参列表为空,但()不可省略。
函数声明与函数原型
主函数调用某函数之前对被调函数进行的说明称为函数声明,其类型有
#include"头文件名.h" 和 int sth(int x,int y);
需注意:函数声明和函数定义是两种不同的概念。函数定义指的是对函数完整功能的确定,包括函数首部(函数名、函数类型、形参、形参类型)、函数体等的指定。函数声明是将函数首部各部分通知编译系统,以便进行调用。函数声明是用函数定义的首部加分号组成。
函数原型:函数类型 函数名(参数类型1,参数类型2…); 或 函数类型 函数名(参数类型1 参数名1,参数类型2 参数名2…);
在进行函数声明时应保证函数原型与函数首部写法上一致,即函数类型、函数名、参数类型、参数个数等一一对应。
-
函数c++_C程序流程设计函数
2021-01-13 03:05:37C是模块化程序设计语言一、函数的定义一般格式函数类型 函数名(形参类型说明表){ 说明部分 语句部分}程序举例例空函数 dummy( ) { }例 无参函数 printstar( ) { printf(“**********\n”); }或 printstar(void ) { ...C是模块化程序设计语言
一、函数的定义
一般格式
函数类型 函数名(形参类型说明表){ 说明部分 语句部分}
程序举例
例 空函数 dummy( ) { }例 无参函数 printstar( ) { printf(“**********\n”); }或 printstar(void ) { printf(“**********\n”); }例 有参函数(现代风格) int max(int x, y) { int z; z=x>y?x:y; return(z); } 例 有参函数(传统风格) int max(x,y) int x,y; { int z; z=x>y?x:y; return(z); }
二、函数的返回值
返回语句
形式: return(表达式);
或 return 表达式;
或 return;
功能:
使程序控制从被调用函数返回到调用函数中,同时把返值带给调用函数
说明:
- 函数中可有多个return语句
- 若无return语句,遇}时,自动返回调用函数
- 若函数类型与return语句中表达式值的类型不一致,按前者为准,自动转换------函数调用转换
- void型函数
例 无返回值函数 void swap(int x,int y ) { int temp; temp=x; x=y; y=temp; }
三、函数的调用
调用形式
函数名(实参表);
说明:
实参与形参个数相等,类型一致,按顺序一一对应
实参表求值顺序,因系统而定(TurboC 自右向左)
函数的调用方式
函数语句: 例 printstar(); printf(“Hello,World!\n”); 函数表达式: 例 m=max(a,b)*2; 函数参数: 例 printf(“%d”,max(a,b)); m=max(a,max(b,c));
对被调用函数要求:必须是已存在的函数
库函数:
#include
用户自定义函数:函数类型说明
函数说明
一般形式:
函数类型 函数名(形参类型 [形参名],….. ); 或 函数类型 函数名();
作用:告诉编译系统函数类型、参数个数及类型,以便检验函数定义与函数说明不同
函数说明位置:程序的数据说明部分(函数内或外)下列情况下,可不作函数说明
若函数返值是char或int型,系统自动按int型处理
被调用函数定义出现在主调函数之前
有些系统(如BorlandC++)要求函数说明指出函数返值类型和形参类型,并且对void和int型函数也要进行函数说明
四、函数参数及传递方式
形参与实参
形式参数:定义函数时函数名后面括号中的变量名
实际参数:调用函数时函数名后面括号中的表达式
例 比较两个数并输出大者main(){ int a,b,c; scanf("%d,%d",&a,&b); c=max(a,b); printf("Max is %d",c);}max(int x, int y){ int z; z=x>y?x:y; return(z);}
说明:
实参必须有确定的值
形参必须指定类型
形参与实参类型一致,个数相同
若形参与实参类型不一致,自动按形参类型转换———函数调用转换
形参在函数被调用前不占内存;函数调用时为形参分配内存;调用结束,内存释放
参数传递方式
方式:函数调用时,为形参分配单元,并将实参的值复制到形参中;调用结束,形参单元被释放,实参单元仍保留并维持原值
特点:
形参与实参占用不同的内存单元
单向传递
例 交换两个数#include main(){ int x=7,y=11; printf("x=%d,\ty=%d\n",x,y); printf("swapped:\n"); swap(x,y); printf("x=%d,\ty=%d\n",x,y);}swap(int a,int b){ int temp; temp=a; a=b; b=temp;}
五、函数的地址传递
方式:函数调用时,将数据的存储地址作为参数传递给形参
特点:
形参与实参占用同样的存储单元
“双向”传递
实参和形参必须是地址常量或变量
例 交换两个数swap(p1,p2)int *p1,*p2;{ int p; p=*p1; *p1=*p2; *p2=p;}main(){int a,b; scanf("%d,%d",&a,&b); printf(“a=%d,b=%d\n”,a,b); printf(“swapped:\n”); swap(&a,&b); printf(”a=%d,b=%d\n",a,b);}
六、函数的嵌套与递归调用
嵌套调用
C规定:函数定义不可嵌套,但可以嵌套调用函数
例 求三个数中最大数和最小数的差值#include int dif(int x,int y,int z); int max(int x,int y,int z); int min(int x,int y,int z);void main(){ int a,b,c,d; scanf("%d%d%d",&a,&b,&c); d=dif(a,b,c); printf("Max-Min=%d\n",d); }int dif(int x,int y,int z){ return max(x,y,z)-min(x,y,z); }int max(int x,int y,int z){ int r; r=x>y?x:y; return(r>z?r:z); }int min(int x,int y,int z){ int r; r=x return(r }
递归调用
定义:函数直接或间接的调用自身叫函数的递归调用
说明
C编译系统对递归函数的自调用次数没有限制,每调用函数一次,在内存堆栈区分配空间,用于存放函数变量、返回值等信息,所以递归次数过多,可能引起堆栈溢出
七、数组作为函数参数
数组元素作函数实参—值传递
地址传递
在主调函数与被调函数分别定义数组,且类型应一致
形参数组大小(多维数组第一维)可不指定
形参数组名是地址变量
例 两个数组大小比较a和b为有10个元素的整型数组比较两数组对应元素变量n,m,k记录a[i]>b[i], a[i]==b[i],a[i]最后 若n>k,认为数组a>b 若n 若n==k,认为数组a==b
#include main(){ int a[10],b[10],i,n=0,m=0,k=0; printf("Enter array a:\n"); for(i=0;i<10;i++) scanf("%d",&a[i]); printf("Enter array b:\n"); for(i=0;i<10;i++) scanf("%d",&b[i]); for(i=0;i<10;i++) { if(large(a[i],b[i])==1) n=n+1; else if(large(a[i],b[i])==0) m=m+1; else k=k+1; } /* Output */}int large(int x,int y){ int flag; if(x>y) flag=1; else if(x-1; else flag=0; return(flag);}
例 求学生的平均成绩 #include float average(int stu[10], int n); void main(){ int score[10], i; float av; printf("Input 10 scores:\n"); for( i=0; i<10; i++ ) scanf("%d", &score[i]); av=average(score,10); printf("Average is:%.2f", av); } float average(int stu[10], int n){ int i; float av,total=0; for( i=0; i total += stu[i]; av = total/n; return av; }
往期回顾
01
|ESP8266模块详解
02
|DA转换器是什么?快来一起学习一下吧!
03
|STM32中断优先级详解
04
|STM32下载程序新思路--使用串口下载程序
-
使用了指针,但是函数的形参仍然无法传递给实参
2020-06-09 10:25:11这是个顺序表,自定义的函数MakeEmpty(SqList *S)对顺序表进行初始化,但是初始化后的S的形参的值length=0,无法传递给实参。请问是为什么啊,然后怎么在这个函数内部能让形参传递给实参呢? ``` #include #... -
函数,结构体,链表简单总结
2020-12-17 23:12:15数据类型 函数名(形参说明表){ 说明语句序列; 可执行语句序列; } 1.函数的”数据类型”指出该函数通过return返回值的类型,除了常用的各种数据类型如int、float、char等外,还有一种特殊类型即... -
C语言 数据类型解读
2018-01-23 22:17:28(1)如何完成不同数据类型之间的强制转换?...主要是要把(类型说明符)表达清楚。 (2)形参和实参的区别? 实参是属于主调函数的局部变量,形参是被调函数的局部变量。形参是定义函数时使用的参数,作用在于当该 -
C++模板和用双向链表实现queue队列
2014-10-24 20:44:00使用C++模板: ...说明: template是一个声明模板的关键字,表示声明一个模板关键字class不能省略,如果类型形参多余一个 ,每个形参前都要加class <类型 形参表>可以包含基本数据类型可以包含类类... -
(C++)类模板(用顺序表实现举例)
2020-10-18 11:08:42现在我们就以顺序表的实现来说明: 类模板 1.格式 template<typename 形参名,typename 形参名,typename 形参名,……> class 类名{ 。。。。。 }; 以template开头,后接模板形参列表(注意形参列表不能为... -
C语言运算符优先级表
2018-03-22 15:44:44优先级运算符名称或含义使用形式结合方向说明1[]数组下标数组名[常量表达式]左到右 ()圆括号(表达式)/函数名(形参表) .成员选择(对象)对象.成员名 ->成员选择(指针)对象指针->成员名 2-负号... -
C++类型转换操作符和转换构造函数
2018-05-06 10:45:57定义:类型转换操作符(type conversion operator)是一种特殊的类成员函数,它定义... 转换函数必须是成员函数,不能指定返回类型,并且形参表必须为空;返回值是隐含的,返回值是与转换的类型相同的,即为上面原型... -
模板和泛型编程 --实例化-- C++ primer 第十六章(2)
2015-03-24 13:36:02模板类型形参可作为类型说明符在模板中的任何地方,与内置类型说明符或类类型说明符的使用方式完全相同。具体而言,它可以用于指定返回类型或函数形参类型,以及在函数体中用于变量声明或强制类型转换。 // ok: same... -
顺序表的建立及操作(数据结构与算法)-C语言
2020-03-25 17:33:07(2)引用类型作形参,在内存中并没有产生实参的副本,它直接对实参操作;而一般变量作参数,形参与实参就占用不同的存储单元,所以形参变量的值是实参变量的副本。 因此,当参数传递的数据量较大时,用引用比用一般... -
友元函数的说明
2015-06-25 19:28:03friend 类型名 友元函数名(形参表); 然后在类体外对友元函数进行定义,定义的格式和普通函数相同,但可以通过对象作为参数直接访问对象的私有成员 说明如下 1)必须在类的说明中说明友元函数,说明时以关键字... -
第16章 模板与泛型编程(3)
2011-12-21 10:58:58模板类型形参可作为类型说明符用在模板中的任何地方,与内置类型说明符或类类型说明符的使用方式完全相同。具体而言,它可以用于指定返回类型或函数形参类型,以及在函数体中用于变量声明或强制类型转换。 ... -
C语言运算符优先级、格式字符、数据类型内存
2019-12-25 10:19:26(表达式)/函数名(形参表) . 成员选择(对象) 对象.成员名 -> 成员选择(指针) 对象指针->成员名 2 - 负号运算符 -算术类型表达式 右到左 单目运算符 (type) 强制类型转换 (纯量数据类型)纯... -
C#运算符执行顺序对照表:在线查看C#运算符执行优先级别
2020-08-12 10:32:22(表达式)/函数名(形参表) . 成员选择(对象) 对象.成员名 -> 成员选择(指针) 对象指针->成员名 2 - 负号运算符 -表达式 右到左 单目运算符 (类型) ... -
C++ 异常说明/规范
2009-12-08 15:22:001. 概念 异常说明/规范(exception specification)指定, 如果... 定义 异常说明跟在函数形参表之后. 一个异常说明在关键字throw之后跟着一个(可能为空的)由圆括号括起来的异常类型列表. 如: void foo(int) throw (std::l -
C++中的异常说明
2012-12-28 17:07:56查看普通函数声明的时候,不可能确定该函数会抛出什么异常,但是,为了编写适当的catch子句,了解函数是否抛出异常以及会抛出那种...异常说明跟在函数形参表之后。一个异常说明在关键字throw之后跟着一个(可能为空)由 -
语文c语言教学.pptx
2020-04-20 00:01:40函数类型 函数名形参表 形参类型说明 { 说明部分 语句部分 }; 返回语句 形式 return(表达式) 或 return 表达式; 或 return; 功能使程序控制从被调用函数返回到调用函数中同时把返值带给调用函数 说明 函数中可有多个... -
C++学习笔记十六-模板和泛型编程(一)
2015-01-14 13:50:24模板和泛型编程 一 、模板定义 ...a. 模板定义以关键字 template 开始,后接模板形参表,模板形参表是用尖括号括住的一个或多个模板...非类型形参跟在类型说明符之后声明,类型形参跟在关键字 class 或 typename 之 -
模板编程 学习
2012-12-12 14:44:38模板分为函数模板和类模板 1、函数模板是一个独立于类型的函数,可作为一种方式,产生函数的特定类型版本。 模板定义以关键字 template 开始,后接...非类型形参跟在类型说明符之后声明。类型形参跟在关键字 class 或 -
C++模板初探
2015-03-24 17:42:43模板定义以关键字template开始,后接模板形参表(template parameter list),模板形参表是用尖括号括住的一个或者多个模板形参的列表,形参之间...非类型形参跟在类型说明符之后声明。类型形参跟在关键字class或typena -
C++模板简单解释
2020-07-04 10:18:34C++模板 函数模板 C++提供的函数模板可以定义一...其中,类型形参表可以包含基本数据类型,也可以包含类类型。类型形参需要加上class / typename 每一个类型形参都需要使用class / typename。 template <class T> -
c++ primer学习之--------模板
2011-02-22 11:15:00模板定义以关键字template开始,后接模板形参表,模板形参表是用尖括号扩住的一个或多个模板形参的列表,形参之间以逗号分隔。...1. inline函数模板 说明符放在模板形参表之后、返回类型之前,不能放在关键字templat -
通过虚函数实现运行时多态(类型转换规则举例改进)
2020-08-13 16:41:14virtual 函数类型 函数名(形参表); 虚函数声明只能出现在类定义中的函数原型声明中,而不能在成员函数实现的时候。 在派生类中可以对基类中的成员函数进行覆盖。 虚函数一般不声明为内联函数,因为对虚函数的调用... -
函数的指针
2014-11-02 15:23:32函数类型由其返回类型以及形参表确定,而与函数名无关。如下声明了一个函数指针: bool (*pFunc)(int, double); 这个语句将pFunc声明为指向函数的指针,它所指向的函数带有两个类型分别为int和double的形参及一... -
模版与泛型编程
2013-12-27 15:31:04一、模版定义 1、定义函数模版 函数模版是一个独立于类型的函数,可作为一种方式,产生函数的特定类型版本。模版定义一关键字template开始,后接模版形参表,... 类型形参由关键字class或typename后接说明符构成,在模