• C和C++引用传递和数组传参引用


    引用传递有两种传参方式,具体可参考文章

    概括地讲,就是

    • *声明一个形参是指针,所以需要传递指针实参,对应的函数实现也应当遵循指针的语法。这种实现思路并不针对于C或者C++,因为它们都有指针,所以都可以通过指针来达到引用传参的效果,但是这种实现本质上不叫引用传参,因为传递的是指针,而不是实参的引用。

    • &这个操作符,在形参声明时,表示该形参是一个引用,不同于指针也不是取地址操作符,该引用操作符属于C++的标准。函数被调用时,不会在内存中开辟新的空间,而是相当于给实参起了一个新名字,比如说如下代码中:

      void fun(int &a){
          a=2;
      }
      //调用fun函数
      int num = 1;
      fun(num);
      

      在这个代码中,调用fun函数时,没有给a形参开辟内存空间,a实际上就是num变量的别名,a和num属于完全一样的存在。

    参考链接:

    https://stackoverflow.com/questions/57483/what-are-the-differences-between-a-pointer-variable-and-a-reference-variable-in

    https://stackoverflow.com/questions/2229498/passing-by-reference-in-c

    理解了指针传参和引用传参,再讲一下数组传参。

    先思考一下,下面这段代码的输出

    #include<iostream>
    using namespace std;
    //通过数组名称传递
    void fun1(int arr[]);
    //通过指针传递
    void fun2(int *arr);
    int main() {
    	int arr[2] = {2,0};
    	fun1(arr);
    	for(int i=0; i<2; i++) {
    		cout<<arr[i]<<endl;
    	}
    	
    	cout<<endl<<endl;
    	fun2(arr);
    	for(int i=0; i<2; i++) {
    		cout<<arr[i]<<endl;
    	}
    
    }
    
    void fun1(int arr[]) {
    	arr[0]=9;
    	arr[1]=8;
    
    }
    void fun2(int *arr) {
    	arr[0]=7;
    	*(++arr)=6;
    }
    

    Output:

    截图_20191105023750.png

    我们知道数组的本质就是一连串相同数据类型的数据,在内存中是连续存放的,同时数组的名称,就是一个指针,它指向了第一个元素【下标为0】,所以,

    fun1(int arr[])
    fun2(int *arr)    
    

    这两种方式完全一样,本质都是指针。既然如此,那么就需要理解对指针的操作了。

    //1.使用[]符号
    /*
    通过示例程序,可以发现,直接通过'指针[i]'操作,可以直接对相应的数组元素进行修改
    */
    arr[0]=9;
    arr[1]=8;
    
    
    //2.对指针进行算数运算
    /*
    arr的值实际上是一个内存地址,同一平台下指针大小都相同
    比如PC x86上是4字节,x64上是8字节
    但是,不同类型的指针步长不同,比如int类型的指针为4个字节,char类型指针步长为1个字节
    所以下面这行代码,如果arr是int类型指针,假设它的值为000000000062FE10,那么++arr之后,它的值为000000000062FE14
    如果arr是char类型指针,假设它的值为000000000062FE10,那么++arr之后,它的值为000000000062FE11
    */
    ++arr;
    
    //3.指针解引用
    /*
    通过'*'对指针进行解引用操作
    */
    
    //4.取出指针的地址'&'
    /*
    &是取址操作符,但是好像对指针取址也没有什么意义吧
    */
    

    联想到这里,再谈一个容易出错的误区,先思考一下如下代码的输出:

    //数组传参求数组长度
    #include<stdio.h>
    int sizeofarr(int arr[]) {
    	printf("%d
    ",sizeof(arr));
    	printf("%d
    ",sizeof(arr[0]));
    	printf("%d
    ",sizeof(int));
    
    	return sizeof(arr)/sizeof(int);
    }
    int main() {
    	int arr[10] = {2,0,9,3,2,1,2,5,6,7};
    	printf("size of arr calculating by parameter: %d",sizeofarr(arr));
    	
    	printf("
    
    %d
    ",sizeof(arr));
    	printf("%d
    ",sizeof(arr[0]));
    	printf("%d
    ",sizeof(int));
    	
    	printf("the actual size of arr: %d",sizeof(arr)/sizeof(arr[0]));
    	return 0;
    }
    

    sizeof(arr)/sizeof(arr[0])这是一个十分常用的求数组长度的方法,前提是,不把arr传递到函数里面求长度,为什么这么说呢?参考如下打印结果:

    截图_20191105031031.png

    我的机子是64位的,所以sizeof(pointer)就是8,所以通过函数来求数组长度得到的结果就是2。

    那么如何避免这种错误呢?

    要么函数再加一个参数,表示数组的长度,要么定义一个全局的常量表示数组的长度。

    参考链接:https://stackoverflow.com/a/10349610

  • 相关阅读:
    javascript设计模式小记
    静态iframe异步加载
    博客搬家分割线
    大数据学习之MapReduce篇
    IDEA 创建javaWeb以及Servlet
    数组定义 二维数组 数组遍历 查找
    201720181 JAVA实验站 第二周作业
    201720181 JAVA实验站 第三周作业
    201720181 团队名称 第一周 作业
    C#语言编写的基于directshow的音视频格式转换
  • 原文地址:https://www.cnblogs.com/ericling/p/11798608.html
Copyright © 2020-2023  润新知