C++函数参数

C++中一个很重要也是最基本的概念,函数,这节我们来看看C++中函数在实际中的应用


1.函数的声明

这和大多数编程语言一样,访问修饰符    返回类型   函数名(参数)

2.函数的参数

这个很重要,函数的形参,基本数据类型就不说了,主要来看一下C++中特有的指针参数,引用形参,以及数组作为形参等

其实说到底,函数只有两种传递参数的方式:

1.按值传递,比如:传递基本数据类型   int这些都是按值传递的

2.另外就是传地址,  这个就是我们接下来要详细介绍的用指针引用数组等作为形参

2.1指针形参

#include<iostream>
using namespace std;
void testfunction(int* p);
void main()
{
	int i=3;
	int* p=&i;
	testfunction(p);
	cout<<"main:"<<*p<<endl;//Print: main:10
}
void testfunction(int* p)
{
	*p=10;
	cout<<"testfunction:"<<*p<<endl;//Print: testfunction:10
}


从上面代码段来看,形参的值改变之后,实参的值也改变了。我们在看一下下面的代码块:
#include<iostream>
using namespace std;
void testfunction(int* p);
void main()
{
	int i=3;
	int* p=&i;
	testfunction(p);
	cout<<"main:"<<*p<<endl;//Print: main:3
}
void testfunction(int* p)
{
	int i=10;
	p=&i;
	cout<<"testfunction:"<<*p<<endl;//Print: testfunction:10
}


把形参的指向改变后,不影响实参,这个怎么解释呢?看图说明
这是第二份代码在内存中的示意图,从中可以看出指针也在内存中占据一块内存空间,至于第一份代码中为什么能改变 i 的值,那是因为形参和实参都同时指向一块内存空间

2.2数组形参

用数组作为形参:
#include<iostream>
using namespace std;
void testfunction(int p[]);
void main()
{
	int i[]={1,2};
	testfunction(i);
	cout<<"main:"<<i<<endl;//Print: main:003CFC08
	cout<<"main:"<<i[1]<<endl;//Print: main:10
}
void testfunction(int p[])
{
	p[1]=10;
	cout<<"testfunction:"<<p<<endl;//Print: testfunction:003CFC08
	cout<<"testfunction:"<<p[1]<<endl;//Print: testfunction:10
}


这里可以看出输出数组的内存地址,形参和实参的地址是一模一样的,所以形参改变,实参也改变。这是为什么呢??

上诉代码等同于下面的代码:
#include<iostream>
using namespace std;
void testfunction(int* p);
void main()
{
	int i[]={1,2};
	testfunction(i);
	cout<<"main:"<<i<<endl;//Print: main:003CFC08
	cout<<"main:"<<i[1]<<endl;//Print: main:10
}
void testfunction(int* p)
{
	*(p+1)=10;
	cout<<"testfunction:"<<p<<endl;//Print: testfunction:003CFC08
	cout<<"testfunction:"<<p[1]<<endl;//Print: testfunction:10
}


这样结合我们指针作为形参所在内存中分布的示意图就能够解释了。

2.3 引用形参

还记得我们说过,引用其实就是指针常量,指针常量里面的值是可以改变的,只是地址不能改变

#include<iostream>
using namespace std;
void testfunction(int &p);
void main()
{
	int i=2;
	testfunction(i);
	cout<<"main:"<<i<<endl;//Print: main:10
}
void testfunction(int &p)
{
	p=10;
	cout<<"testfunction:"<<p<<endl;//Print: testfunction:10
}


引用是特殊的指针,它由编译器自动解引用,如果我们自己手动解引用就是如下代码:

#include<iostream>
using namespace std;
void testfunction(int* const p);
void main()
{
	int i=2;
	testfunction(&i);
	cout<<"main:"<<i<<endl;//Print: main:10
}
void testfunction(int* const p)
{
	*p=10;
	cout<<"testfunction:"<<*p<<endl;//Print: testfunction:10
}



3.4 采用const修饰形参

上面3.3中我已经使用了一种const修饰,上面的是指针常量,指向地址不能改变,那么我们如果希望形参的值不能改变,就应该使用常量指针。

#include<iostream>
using namespace std;
void testfunction(const int*  p);
void main()
{
	int i=2;
	testfunction(&i);
	cout<<"main:"<<i<<endl;//Print: main:10
}
void testfunction(const int* p)
{
	int i=10;
	p=&i;
	cout<<"testfunction:"<<*p<<endl;//Print: testfunction:10
}



正在指针那节中已经介绍过了,可否理解

还有一些多变的,比如:
#include<iostream>
using namespace std;
int* const testfunction(int* const  p);
void main()
{
	int i=2;
	int* const p=testfunction(&i);
	cout<<"main:"<<*p<<endl;//Print: main:10
}
int* const testfunction(int* const p)
{
	*p=10;
	cout<<"testfunction:"<<*p<<endl;//Print: testfunction:10
	return p;
}


只要理解了指针常量和常量指针的区别,然后结合他们在内存中的分布图,就算在怎么变化的复杂都可以理解了


4.C++可变参数

C++可变参数是一个重要的概念,具体使用方式如下
#include<iostream>
using namespace std;
int testfunction(int count,...);
void main()
{
	cout<<testfunction(3,4,6,5)<<endl;
}
int testfunction(int count,...)
{
	int sum=0;
	va_list arg_ptr;
	_crt_va_start(arg_ptr,count);
	for (int i = 0; i < count; i++)
	{
		sum+=_crt_va_arg(arg_ptr,int);
	}
	_crt_va_end(arg_ptr);
	return sum;
}


输出的结果是:4+6+5    15

第一个3表示有三个值

这里还有三个宏   _crt_va_start,_crt_va_arg,_crt_va_end     也可以导入头文件cstdarg后          va_start,va_arg,va_end     这三个宏的意思看名字就理解了

或者可以查看源码后,自己替换跟踪一下看看

#include<iostream>
using namespace std;
int testfunction(int count,...);
void main()
{
	cout<<testfunction(3,7,6,5)<<endl;
}
int testfunction(int count,...)
{
	int sum=0;
	va_list arg_ptr;
	//等同于_crt_va_start(arg_ptr,count)
	arg_ptr=(va_list)_ADDRESSOF(count)+_INTSIZEOF(count);
	/*  等同于for (int i = 0; i < count; i++){sum+=_crt_va_arg(arg_ptr,int);}*/
	for (int i = 0; i < count; i++)
	{
		//等同于 sum+=_crt_va_arg(arg_ptr,int);
		arg_ptr+=_INTSIZEOF(int);
		sum+=*(int *)(arg_ptr-_INTSIZEOF(int));
	}
	//等同于_crt_va_end(arg_ptr);
	arg_ptr=0;
	return sum;
}


主要是还不懂位运算,搞半天还是不知道_INTSIZEOF宏在做什么,反正一直都是反回4来着
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值