c++之函数形参和实参讲解

1、非地址型参数

在c++中实现模块化编程时,我们形成会遇到对自定义的函数模块传入参数的操作,即形参。这里主要讲解一个非地址型的形参。

不多说,先看代码:

 #include <iostream>

 using namespace std;

 void changeNumber(int num){
     num ++;
 }

 int main(){
     ;
     //猜猜num的值是多少
     changeNumber(num);
     cout << "num = " << num << endl;
     ;
 }

我们从上面的代码可以看到,我们通过一个函数模块对num的值进行了修改,但是最后的输出会是多少呢,是10还是9呢。

我们来看一下控制台的输出结果:

输出结果显示的9,而不是10,那么这是为什么呢,在这之前我们先看看函数体内部的值是多少。

我们可以看到函数体内部的num的值是10,而主函数内的num依旧是9,并没有改变。

这是因为,传入给changeNumber(num);函数模块的num是一个形参,因为,函数的返回值是一个void类型,也就是无类型,那么该函数模块只是执行函数模块内部的代码并不会返回任何的值。但是就是说,虽然都是一个叫做num的变量,但是在changeNumber(num);体内,num的作用域仅仅在函数模块体内有用,一旦函数模块执行完毕,那么num的作用域也就结束了。实际上是内存中有两块不同的内存空间,他们的变量名都是num,但是实际上的值确实不一样的。如下图所示:

从图中我们可以看到主函数和自定义函数模块中的num变量的内存地址是不一样的。

但是如果我们换一种写法那就是截然不同的结果。

看代码:

 #include <iostream>

 using namespace std;

 void changeNumber(int &num){ <-修改的地方  加了一个&符号
     num ++;
     cout << &num <<" in the model : num = " << num << endl;

 }

 int main(){
     ;
     //猜猜num的值是多少
     changeNumber(num);
     cout << &num << " num = " << num << endl;
     ;
 }

从代码中我们可以看到,我仅仅只是在changeNumber()函数模块的形参部分修改了一点点,也就是加了一个引用的符号,取地址的意思,这样的结果将是截然不同,

看运行结果图:

从结果图中,我们可以看到,主函数和函数模块内部的变量num都是同一个变量(内存地址一样就是一样的变量),且最终在主函数中的num和函数模块里面的num的值都发生了改变。

原因:在非数组型形参中,形参只是实参的一份拷贝,也就是说是一个局部变量,通过变量对该变量赋值改变其值,只是在一个局部作用域中对变量进行改变,但是全部的变量(变量名相同)并没有改变。但是数组型形参是与此不同。

2.地址型参数

当我们给自定义的函数模块传入的是一个数组时,那么传入的就是当前数组的第一个元祖的地址,因为在内存中,数组就是一串连续的地址空间。先来看一段代码:

#include <iostream>

using namespace std;

void changeNumber(int &num){
    num ++;
    cout << &num <<" in the model : num = " << num << endl;

}

void changeArray(int arrayInt[], int len){ //此时传入的是数组的第一个元素的地址,类似指针操作
    /*
    if(len > sizeof(arrayInt) / sizeof(int)){
        cout << "输入的数组大小越界。" << endl;
    }
    ; i < len;i++){
        arrayInt[i] = i;
    }
}

void printArray(int arrayyInt[], int len){
    /*
    cout << "len= " << len<<endl;
    cout << "sizeof(arrayInt) / sizeof(int)= " << sizeof(arrayInt) / sizeof(int) <<endl;//输出为1

    因为传入的数组是一个头元素的地址也即指针地址,所以只有单位长,也就是一个int单位长,所以得到的值为1
    在main函数体内得到的值为真实的数组的大小长度

    if(len > (signed)(sizeof(arrayInt) / sizeof(int)) ){  //前者是有符号整数,后者是无符号整数

        cout << "输入的数组大小越界。" << endl;
    }
    */
    //打印

    cout << ;i<len;i++){
        cout << arrayyInt[i] <<endl;
    }
    cout << "-----print-----" <<endl;
}

int main()
{

    ]{,,,,};//原始数组的数值
    cout << "原始输出:" <<endl;
    cout << "arrayInt=" <<endl;
    printArray(arrayInt,);
    //开始改变

    changeArray(arrayInt,sizeof(arrayInt) / sizeof(int));
    cout << "改变之后:"<<endl;
    cout <<"arrayInt=" <<endl;
    printArray(arrayInt,sizeof(arrayInt) / sizeof(int));
    ;
}

运行结果如图所示:

从图中可以看到,同样的操作,对于int型的整数num和对于只能存放int型的数组来讲,c++对其做的改变是不一样的。这里对形参的操作其实也是对实参的操作,因为如果对数组实参进行一份拷贝的话,会增加很大的内存消耗,所以c++就直接修改了实参值。

当然对于数组的操作,还有一种指针的传参方式,先看代码:

 void printPointArray(int* arrayInt,int len){
     ;i<len;i++){
         cout << *(arrayInt+i) << endl;
     }
 }

从代码中我们看到,我们只是修改了打印数组的一个自定义函数,数组的参数传递有两种方式,一种是指针的方式:void printPointArray(int* arrayInt,int len),另一种是数组的方式:void printArray(int arrayInt[],int len),不管哪一种,都是传入一个数组的首地址。

c++之函数形参和实参的更多相关文章

  1. python之函数形参、实参、可变长参数整体使用和分类

    形参与实参 '''def fn(形参们): pass fn(实参们)'''# 形参:定义函数,在括号内声明的变量名,用来结束外界传来的值# 实参:调用函数,在括号内传入的实际值,值可以为常量.变量.表 ...

  2. python函数—形参、实参、位置参数、关键字参数

    1.通过def function_name([parameter]): 定义,函数一遇到return即结束运行.如果函数没有定义返回值,则返回None,如果定义了一个返回值,则返回该对象,如果一个re ...

  3. 【学习笔记】--- 老男孩学Python,day10, 初识函数 形参、实参

    函数:对功能的封装语法: def 函数名(形参): 函数体 函数名(实参) 函数名:命名规则和变量一样 函数的返回值: return, 函数执行完毕. 不会执行后面逻辑 1. 如果函数中不写retur ...

  4. js函数形参和实参的区别

    在<Javascript权威指南>中这样定义: 参数有形参(parameter)和实参(argument)的区别,形参相当于函数中定义的变量,实参是在运行时的函数调用时传入的参数. 说明白 ...

  5. C++函数形参与实参交换

    c++中函数的实参传递到形参的值是单向的,改变形参并不会影响实参. #include <iostream> using namespace std; void swap(int a, in ...

  6. JavaScript中函数的形参和实参的实现原理剖析

    我们都知道JS里面参数的传递是可以不一样的,比如我们有一个函数: <script type="text/javascript"> function one(a,b,c) ...

  7. javascript . 03 函数定义、函数参数(形参、实参)、函数的返回值、冒泡函数、函数的加载、局部变量与全局变量、隐式全局变量、JS预解析、是否是质数、斐波那契数列

    1.1 知识点 函数:就是可以重复执行的代码块 2.  组成:参数,功能,返回值 为什么要用函数,因为一部分代码使用次数会很多,所以封装起来, 需要的时候调用 函数不调用,自己不会执行 同名函数会覆盖 ...

  8. Pyhton函数篇(一)之函数中的形参与实参

    1:什么是函数 函数其实就是带名字的代码块,用于完成一些具体的工作.如果我们在写一段程序的时候,需要多次用到同样的一个功能,如果每次都要重复写相同的代码,不仅会增加我们的代码量,更会让我们写出的代码让 ...

  9. 函数的形参和实参之arguments对象

    当函数调用函数时候传入的实参比函数声明时候制定的形参要少时候,剩余的形参就设置成了undefined.例如 function getPropertyNames(o,/*optional*/a){ va ...

随机推荐

  1. c++静态变量与菲静态变量

    刚开始用C++写程序,遇到了一个很奇怪的问题,就是在类定义的面定义了一个静态成员变量,但在使用时编译器报错称变量不是类的成员. 文件a.h内容: /**********************A.h* ...

  2. Associate File Type with Qt In Mac Os and Win

    Win Registry Question One day, my boss want me to finish one function which let the users can double ...

  3. mysql查询赋值、修改拼接字符串

    sql中修改字符串类型的字段可以这么拼接:update tbName set UserName='abc'+UserName; 但mysql中就不行了,需要这样:update tbName set U ...

  4. java关于split分割字符串,空的字符串不能得到的问题

    java关于split分割字符串,空的字符串不能得到的问题   class T { public static void main(String args[]) { String num[] = ne ...

  5. 不要怂,就是GAN (生成式对抗网络) (二):数据读取和操作

    前面我们了解了 GAN 的原理,下面我们就来用 TensorFlow 搭建 GAN(严格说来是 DCGAN,如无特别说明,本系列文章所说的 GAN 均指 DCGAN),如前面所说,GAN 分为有约束条 ...

  6. 在Eclipse中使用Struts和Hibernate框架搭建Maven Web项目

    前言 学习使用Java还是2012年的事情,刚开始学习的Java的时候,使用的是MyEclipse工具和SSH框架.初学者适合使用MyEclipse,因为他将struts.Spring和Hiberna ...

  7. Yii2 upload

    http://webtips.krajee.com/advanced-upload-using-yii2-fileinput-widget/ http://webtips.krajee.com/upl ...

  8. 浅析互联网系统和传统企业IT系统的异同

    前不久,一则中行宕机的消息引起了网上IT人士的热议.其中对于大型机或者RISC系统的稳定性可靠性的质疑更是热议中的主流声音,很多人拿现在互联网系统做对比,认为大型机所谓的几个9都是吹出来的云云.在这里 ...

  9. 如何搭建eclipse+maven环境

    Maven这个个项目管理和构建自动化工具,越来越多的开发人员使用它来管理项目中的jar包.本文仅对Eclipse中如何安装.配置和使用Maven进行了介绍.完全step by step. 如果觉得本文 ...

  10. 在TFS 2013的敏捷组合管理中添加积压工作

    在TFS提供的三套默认模板中,组合管理(Portfolio Management)只包含功能(Feature)和要求这个两个积压工作.你可以参考下面的文档,学会如何在积压工作中添加额外的工作项类型. ...