参数传递:传值参数,指针形参,传引用参数,const形参和实参,数组形参,main:处理命令行选项,含有可变形参的函数

重点:

1.每次调用函数时都会重新创建它的形参,并用传入的实参对形参进行初始化。

NOTE: 形参初始化的机理与变量初始化一样。

2.形参的类型决定了形参和实参交互的方式。

(引用->绑定,非引用->拷贝)

3.实参分为:被引用传递(引用形参是实参的别名),被值传递(实参形参是两个相互独立的对象)。

4.传值参数:函数对形参做的所有操作都不会影响实参。

5.指针形参:指针的行为和其他非引用类型一样,当执行指针拷贝操作时,拷贝的是指针的值。拷贝后,两个指针是不同的指针。

NOTE: C程序员常常用指针类型的形参访问函数外部的对象,C++当中,建议使用引用类型的形参代替指针。

6.对于引用的操作实际上是作用在引用所引的对象上。

7.有的类类型不支持拷贝操作,函数只能通过引用形参访问该类型的对象。

8.如果函数无须改变引用形参的值,最好将其声明为常量引用。

例如:编写一个函数比较两个string对象的长度,因为string对象可能会非常长,所以应该尽量避免直接拷贝它们。而比较长度无须改变string对象的内容,所以把形参定义为对常量的引用。

//比较两个string对象的长度

Bool isShorter(const string &s1,const strig &s2)

{

return  s1.size()<s2.size();

}

Note:如果函数无须改变引用参数的值,最好将其声明为常量引用。

9.使用形参返回额外信息。

10.当用实参初始化形参会忽略掉顶层const。换句话说:当形参有顶层const时,传给它常量对象或者非常量对象都是可以的。

void fcn(const int i){/*fcn能够读取i,但是不可以修改i*/}

void fcn(int i ){ // 错误:重复定义了fcn(int i)}

11.C++允许具有相同名字的函数,不过前提是不同函数的形参列表有明显区别,而顶层const被忽略掉了,所以有没有顶层const是一样的。

12.可以使用非常量初始化一个底层const对象,但是反过来不行!

int  i = 42;

Const int *cp = &i; //正确,但是cp不能改变i;

Int *p = cp; //错误,类型不匹配;

Const int &r = i; //正确,但是r不能改变i;

Int &r3 = r; //错误,类型不匹配;

Const int &r2 = 42; // 正确;

Int &r4 = 42; //错误,不能用字面值初始化一个非常量引用;

13.①要想调用引用版本的reset(reset(i)),只能使用int类型的对象。不能使用字面值,求值结果为int的表达式,需要转换的对象,或者const int类型对象。

②想调用指针版本的reset(reset(&i))只能使用int*。

14.尽量使用常量引用:?普通引用函数可以修改它的实参的值;

?普通引用极大地限制了函数所能接受的实参类型。

(例如整型只能int,不可以const对象,字面值,需要类型转换的对象)

15.数组的两个特性:

⑴不允许拷贝数组;

(因此,无法以值传递的方式使用数组参数)

⑵使用数组会将其转换成指针;

(因此当向函数传递一个数组时,实际上传递的是指向数组首元素的指针)

16.尽管不能以值传递的方式传递数组,但是我们可以把形参写成类似数组的形式:(以下三种形式等价)

Void print ( const int* );

Void print ( const int[ ]);

Void print ( const int[10]);

17.管理指针形参:

①使用标记指定数组长度;

//要求数组本身含有一个结束标记;

Void print ( const char *cp )

{

If(cp)  //指针不是空指针

While(*cp) //指针所指的字符不是空字符

Cout << *cp << endl;

}

②使用标准库规范;

//传递指向数组首元素和尾后元素的指针;

Void print ( const int *beg, const int *end )

{
 //输出beg和end之间(不含end)所有元素;

While( beg != end )

Cout << *beg++ << endl;

}

③显示传递一个表示数组大小的形参;

Void print ( const int ia [ ],size_t size)

{

For( size_t int i=0 ; i != size ; i++ )

{

Cout << ia[i] << endl;

}

}

/* 三个print函数都把数组形参定义成了指向const的指针,只有当函数确实要改变元素值的时候,才能把形参定义成指向非常量的指针*/

18.数组引用形参:

&arr两端的括号不可少

F ( int &arr[10] ) //错误:将arr声明成了引用的数组;

F ( int (&arr)[10] ) //正确:arr是具有10个整数的整型数组的引用

19.所谓的多维数组就是数组的数组。

20.多维数组传递给函数,真正传递的是指向数组首元素的指针。因为是数组的数组,所以首元素本身就是一个数组,指针就是一个指向数组的指针

Void print ( int (*matrix)[10] , int rowsize );

Void print ( int matrix[][10] , int rowsize );

size_t 类型 :

size _t 为了增强程序的可移植性,便有了size_t ,不同系统上,定义size_t可能不一样。

经测试发现,在32位系统中size_t是4字节的,在64位系统中,size_t是8字节的,这样利用该类型可以增加程序移植性。

size_t的定义 

它的定义在/usr/include/linux/types.h

                    typedef _kernel_size_t size_t;

21.main:处理命令行选项

Int main(int argc,char *argv[ ]) { ... }

Argc:表示数组中字符串的数量,argv是一个数组,它的元素是指向C风格字符串的指针。SO:等价于

Int main(int argc,char **argv) { ... }

Note:使用argv中的实参时,一定要记得可选的实参从argv[1]开始;argv[0]保存程序的名字,而非用户输入。

22.处理不同数量实参的函数:

①如果所有的实参类型相同,可以传递一个名为initializer_list的标准库类型;

②如果实参的类型不同,我们可以编写一种特殊的函数,也就是所谓的可变参数模板。

23.initializer_list是一种模板类型,类似于vector:

Initializer_list<string> ls;//initializer_list的元素类型为string

Initializer_list<int> li;//initializer_list的元素类型为int

(和vector不同的是,initializer_list对象的元素永远是常量值,不可改变。)

时间: 2024-12-25 19:52:29

参数传递:传值参数,指针形参,传引用参数,const形参和实参,数组形参,main:处理命令行选项,含有可变形参的函数的相关文章

关于函数传参--传指针,传引用

今天和同学讨论到指针和引用的传递问题,有些想法从推理上讲是正确的,但是因为是推理,说出自己观点的时候不是那么有底气,本着实践是检验真理的唯一标准的原则,在电脑上敲了几段代码,验证了推理的正确性. 先上代码,再分析. 代码1: void Swap0(int a1,int b1){ int temp; temp=a1; a1=b1; b1=temp; } void Swap1(int *a1,int *b1){ //交换地址 int *temp; temp=a1; a1=b1; b1=a1; } v

编程题:指针变量,实参与形参的引用。已知一个一维数组,求其中前n个数的和。n由键盘输入。

#include<stdio.h> int sum(int *q,int n) { int i,s=0; for(i=0;i<n;i++,q++) s+=*q; return s; } void main() { int num,a[10]={1,2,3,4,5,6,7,8,9,10}; int *p=a; scanf("%d",&num); printf("%d\n",sum(p,num)); } 编程题:指针变量,实参与形参的引用.已知

传值、传指针、传引用

值传递.指针传递.引用传递的区别 c语言的规则很简单:"所有的参数都是传值调用".在这句话的基础上,我们来分析值传递.指针传递.引用传递的区别. 一.值传递 值传递,这与C函数的性质有关.C函数的所有参数均以"传值调用"方式进行传递,这意味着函数值将获得参数值的一份拷贝,函数可以放心修改这个拷贝值,而不必担心会修改调用程序实际传给他的参数. 我们先来看实现函数swap1: void swap1(int a,int b) { printf("\n\n传值的示

传引用作为形参和返回值_节省参数拷贝的时间

基本的传引用概念 #include <bits/stdc++.h> using namespace std; //说出以下两个函数的区别 int& whatf(int &a,int &b) //如果不希望函数执行过程中 某变量被修改 用const限定 { a=3;b=2; return a; } int whath(int a,int b) { a=3;b=2; return a; } int main() { int a,b; whatf(a,b)++; cout&l

c# 方法参数(传值,传引用,ref,out,params,可选参数,命名参数)

 一.方法参数的类型----值类型和引用类型 当方法传递的参数是值类型时,变量的栈数据会完整地复制到目标参数中即实参和形参中的数据相同但存放在内存的不同位置.所以,在目标方法中对形参所做的更改不会对调用者的初始变量产生任何影响. 当方法传递的参数是引用类型是,只是将变量的引用复制到目标参数中,实参和形参的引用指向内存中的同一位置.所以,在目标方法中对形参所做的更改会影响调用者的初始变量. 二.一些特殊的方法参数 1.引用参数---ref (使值类型的变量做方法参数时也可以传引用) 一些数据类型(

C++传值和传引用

传值参数 首先你肯定明白一个道理:当初始化一个非引用类型的变量时,初始值被拷贝给变量,此时对变量的改动不会涌向初始值 int n = 0; int i = 1; // i是n的副本 i = 42; // i的值改变,n的值不改变 传值参数的机理完全一样,由于每次调用函数时都会重新创建它的形参,并用传入的实参对形参进行初始化,所以函数对形参做的所有操作不会影响实参,如果我们想让函数改变我们传入的实参本身们就可以用到指针形参访问函数外部对象 指针形参 先看一段代码: int n = 0; int i

传递的时候尽量传引用

如果传递对象的效率会低,因为要调用复制构造函数. 传递引用的话,执行效率会很高. main.cpp #include <iostream> #include "TestClass.h" using namespace std; TestClass test(){ TestClass t; return t; } void test1(TestClass testClass){ cout << "对象作为参数传递" << endl;

Go语言的传参和传引用[转]

目录[-] 传参和传引用的问题 传slice不是传引用! 什么叫传引用? 为什么传slice不是传引用? 为什么很多人误以为slice是传引用呢? 传指针和传引用是等价的吗? 所有类型的函数参数都是传值的! 那Go语言有传引用的说法吗? 什么是引用类型, 和指针有何区别/联系 ? 总结 传参和传引用的问题 很多非官方的文档和教材(包括一些已经出版的图书), 对Go语言的传参和引用的讲解 都有很多问题. 导致众多Go语言新手对Go的函数参数传参有很多误解. 而传参和传引用是编程语言的根本问题, 如

C语言命令行参数(main 函数形参)及在控制台窗口的调用

main函数可以带参数,这个参数可以认为是 main函数的形式参数.C语言规定main函数的参数只能有两个, 习惯上这两个参数写为argc和argv.因此,main函数的函数头可写为: main (argc,argv)C语言还规定argc(第一个形参)必须是整型变量,argv( 第二个形参)必须是指向字符串的指针数组.加上形参说明后,main函数的函数头应写为: main (argc,argv) int argv; char *argv[]; 或写成: main (int argc,char *