传值方式

前言

当初学顺序链表的时候,书上就出现了这样的语言,如下所示:

  1. Status InitList_Sq(SqList &L) {
  2. //构造一个空的线性表L。
  3. L.elem = (ElemType *)malloc(LIST_INIT_SIZE* sizeof(ElemType));
  4. if(!L.elem)exit(OVERFLOW);
  5. L.length=0;
  6. L.listsize=LIST_INIT_SIZE;
  7. return OK;
  8. }

这里面的&L第一遍看的时候想当然的认为是取了SqList结构体的L的地址,没有细想。然后又看到了这句。

  1. Status GetElem(SqList L,int i,ElemType &e) //这根本就不是取地址符

这里的ElemType就是int的类型

那么可以写成如下这种方法

  1. Status GetElem(SqList L,int i,int &e)

这样整个倒是显得非常奇怪

那么我们类比这样的形式

  1. int *a,*b; /* 定义了两个整型的指针 */
  2. int **a, **b; /* 定义了整型指针的指针 */
  1. //那么难道说是定义了整型变量为地址的变量e
  2. int &e;

那么我们看下面他写的这个东西:

显然这里可以看出由于L指针指向的是ElemType类型,所以e是ElemType类型的。所以以上类比显然是不对的。

C/C++中的引用参数

查找了很多的资料发现,这个实际上是C++里的形参符号,必须要在跟在数据类型的后面使用。在函数内部对形参的操作都等同于直接操作原变量。

请看下面的例子

1.1 实参值不变

把实参的值传送给函数局部工作区相应的副本中,函数使用这个副本执行必要的功能。函数修改的是副本的值,实参的值不变。

  1. #include <stdio.h>
  2. void swap(float m,float n)
  3. {
  4. float temp;
  5. temp = m;
  6. m = n;
  7. n = temp;
  8. }
  9. void main()
  10. {
  11. float a,b;
  12. printf ("please enter the number of a and b =");
  13. scanf("%f %f",&a,&b);
  14. swap (a,b);
  15. printf ("the number of a = %f, the number of b = %f",a,b);
  16. }

可以看到,a与b的值并没有发生更换。

1.2传地址方式——指针变量做参数,形参变化影响实参

  1. #include <stdio.h>
  2. void swap(float *m,float *n)
  3. {
  4. float temp;
  5. temp = *m; //取指针变量内容
  6. *m = *n;
  7. *n = temp;1
  8. }
  9. void main()
  10. {
  11. float a,b,*p1,*p2;
  12. printf ("please enter the number of a and b =");
  13. scanf("%f %f",&a,&b);
  14. p1=&a;
  15. p2=&b;
  16. swap (p1,p2);
  17. printf ("the number of a = %f, the number of b = %f",a,b);
  18. }

还有第二种方式

  1. #include <stdio.h>
  2. // 利用指针的经典解法
  3. void swap(int *a, int *b)
  4. {
  5. int temp;
  6. temp = *a;
  7. *a = *b;
  8. *b = temp;
  9. }
  10. void main()
  11. {
  12. int a = 1, b = 2;
  13. swap(&a,&b);
  14. printf("%d %d",a,b);
  15. }

可以看到,形参变化影响实参

形参变化不影响实参

  1. #include <stdio.h>
  2. void swap(float *a, float *b)
  3. {
  4. float *temp;
  5. temp = a;
  6. a = b;
  7. b = temp;
  8. }
  9. void main()
  10. {
  11. float a = 1, b = 2;
  12. swap(&a,&b);
  13. printf("%f %f",a,b);
  14. }

可以发现ab值并没有发生变化

1.4 传地址方式——数组名作参数

传递的是数组的首地址 概念:数组名就是数组首地址

对形参数组所做的任何改变都将反映到实参数组中

  1. #include <stdio.h>
  2. #include <string.h>
  3. void sub(char *b) //在C++语言中也可以使用b[]来写
  4. {
  5. strcpy(b,"world");
  6. }
  7. void main()
  8. {
  9. char a[10] = "hello";
  10. sub(a); //传数组首地址
  11. printf("%s",a);
  12. }

1.5 传地址方式——引用类型做参数

什么是引用?

引用:他用来给一个对象提供一个代替的名字

  1. //运用了C++的语法
  2. #include <iostream>
  3. #include <stdio.h>
  4. // 引用参数实现交换
  5. void swap(int &a, int &b){
  6. int temp;
  7. temp = a;
  8. a = b;
  9. b = temp;
  10. }
  11. // Using main to test
  12. int main(){
  13. int a = 1, b = 2;
  14. swap(a,b);
  15. printf("%d %d\n",a,b);
  16. return 0;
  17. }

有些文章说道,通过引用的方式传递给函数的是变量的地址,这种方式叫做地址传递方式,还提到这是和“值传递”十分不同的方式。

有些书说道:“引用实际上是取了个‘别名’

还有的书和文章说道引用是比通过指针传递更加高效的方式,因为不需要开辟新的内存空间用来拷贝实参的地址。

那么SqList *&L和SqList *L的关系就能捋清楚了 可以参考1.2 传地址方式——指针变量做参数,形参变化影响实参

SqList *&L的情况

它的意思是,L是对List的引用,函数体内对L的操作,就相当于对Head的操作,所以这种情况下对L的更改才会发生到List上。

SqList *L的情况

当List指针作为函数参数传进去时,意为你要把指针List所指的地址值赋给指针L,(可以类比int类型,毕竟指针本质上也是一种数据类型)。这就意味着此时的实参List跟形参L并不是同一个指针,而是指向同一个地址的不同指针。所以你对L的操作并没有发生到List身上。达不到预期效果。

最后

C语言不存在“引用”的概念,符号“&”只是表示取地址,而C++才有“引用”的含义。

比如对于这段代码——

  1. //C语言不存在“引用”的概念,符号“&”只是表示取地址,而C++才有“引用”的含义。
  2. //比如对于这段代码——
  3. #include<stdio.h>
  4. int main()
  5. {
  6. int i = 0;
  7. int &j = i;
  8. },
  9. /*使用gcc编译器编译会报错:”错误:expected identifier or ‘(’ before ‘&’ token“,但是使用g++编译就不会报错。*/

在数据结构与算法中 传值方式(C语言)的更多相关文章

  1. java中传值方式的个人理解

    前言 这几天在整理java基础知识方面的内容,对于值传递还不是特别理解,于是查阅了一些资料和网上相关博客,自己进行了归纳总结,最后将其整理成了一篇博客. 值传递 值传递是指在调用函数时将实际参数复制一 ...

  2. 实现数据结构与算法需要掌握的C语言

    我使用C语言并不频繁,一般都是用来实现数据结构与算法,因为面向过程的编程方式容易理解算法的原理,但是呢,如果很长时间没写算法,那么就意味着C语言的某些语法就生疏了,但是总有那么一些,在写算法的时候,特 ...

  3. 数据结构KMP算法中手算next数组

    总结一下今天的收获(以王道数据结构书上的为例子,虽然我没看它上面的...):其中竖着的一列值是模式串前缀和后缀最长公共前缀. 最后求得的结果符合书上的结果,如果是以-1开头的话就不需要再加1,如果是以 ...

  4. 数据结构与算法之顺序表C语言实现

    顺序表等相关概念请自行查阅资料,这里主要是实现. 注: 1.顺序表C语言实现: 2.按较简单的方式实现,主要帮助理解,可在此基础上修改,更加完善: 3.提供几个简单函数,可自行添加功能: 4.可用C+ ...

  5. 数据结构与算法之顺序栈C语言实现

    顺序栈是一种特殊的顺序表,主要操作是入栈和出栈.将顺序表加一些特定限制,就成了顺序栈. 注: 1.顺序栈C语言实现: 2.按较简单的方式实现,主要帮助理解,可在此基础上修改,更加完善: 3.提供几个简 ...

  6. Java数据结构和算法 - OverView

    Q: 为什么要学习数据结构与算法? A: 如果说Java语言是自动档轿车,C语言就是手动档吉普.数据结构呢?是变速箱的工作原理.你完全可以不知道变速箱怎样工作,就把自动档的车子从1档开到4档,而且未必 ...

  7. 数据结构(逻辑结构,物理结构,特点) C#多线程编程的同步也线程安全 C#多线程编程笔记 String 与 StringBuilder (StringBuffer) 数据结构与算法-初体验(极客专栏)

    数据结构(逻辑结构,物理结构,特点) 一.数据的逻辑结构:指反映数据元素之间的逻辑关系的数据结构,其中的逻辑关系是指数据元素之间的前后件关系,而与他们在计算机中的存储位置无关.逻辑结构包括: 集合 数 ...

  8. JavaScript 数据结构与算法之美 - 线性表(数组、栈、队列、链表)

    前言 基础知识就像是一座大楼的地基,它决定了我们的技术高度. 我们应该多掌握一些可移值的技术或者再过十几年应该都不会过时的技术,数据结构与算法就是其中之一. 栈.队列.链表.堆 是数据结构与算法中的基 ...

  9. 【PHP数据结构】在学数据结构和算法的时候我们究竟学的是啥?

    一说到数据结构与算法,大家都会避之不及.这本来是一门专业基础课,但是大部分人都并没有学好,更不用说我这种半路出家的码农了.说实话,还是很羡慕科班出身的程序员,因为你们在日常工作或者面试中,只需要复习一 ...

随机推荐

  1. 解决Wordpress提示FTP登录问题

    向wordpress目录的wordpress-config.php中添加 define("FS_METHOD", "direct"); define(" ...

  2. iOS 模糊、精确搜索匹配功能方法总结 By HL

    字符串搜索主要用于UITableView的搜索功能的筛选,过滤,查询 下面是一些流行的搜索查询方法 一.遍历搜索 for循环 根据要求:精确搜索(判读字符串相等)   模糊搜索(字符串包含) 相关知识 ...

  3. Centos 系统目录概述

    Linux目录一切从根目录开始,即"/",根下面的目录是一个有层次的树状结构.并且分区或磁盘是必须挂载在根目录才可以正常访问.做一个形象的比喻:目录类似一个一个的入口,而根目录则是 ...

  4. 【前端开发日记 】VSCODE被初始化之后重新设置的这些事

    不知到什么插件的原因,导致我的vscode编辑器,在输入比如div的时候按tab不会识别成html标签,在设置了推荐词之后还是不好使,于是初始化了自己的编辑器设置 ,导致所有的插件和个性化设置都不见了 ...

  5. 读源码【读mybatis的源码的思路】

    ✿ 需要掌握的编译器知识 ★ 编译器为eclipse为例子 调试准备工作(步骤:Window -> Show View ->...): □ 打开调试断点Breakpoint: □ 打开变量 ...

  6. 12、Linux基础--挂载磁盘步骤、流处理工具awk(正则 比较 逻辑 算数表达式 流程控制)

    笔记 1.晨考 1.用两种方法,实现将文件中的以# 开头的行把# 去掉 sed -r 's/^#//g' /etc/fstab cat /etc/fstab | tr -d '^#' 2.将文件中的H ...

  7. MySQL explain结果Extra中"Using Index"与"Using where; Using index"区别探究

    问题背景 最近用explain命令分析查询sql执行计划,时而能看到Extra中显示为"Using index"或者"Using where; Using Index&q ...

  8. SQL Server 2005 - 让 SELECT 查詢結果额外增加递增序号

    /* 方法一*/SELECT 序號= (SELECT COUNT(客戶編號) FROM 客戶 AS LiMing                 WHERE LiMing.客戶編號<= Chan ...

  9. 从零搭建Pytorch模型教程(一)数据读取

    ​  前言  本文介绍了classdataset的几个要点,由哪些部分组成,每个部分需要完成哪些事情,如何进行数据增强,如何实现自己设计的数据增强.然后,介绍了分布式训练的数据加载方式,数据读取的整个 ...

  10. linux 解决磁盘占用100%

    df -h 查看磁盘使用情况 ll -h 查看文件的大小   使用如下命令查找大于100M的大文件,发现有几个日志文件及临时文件比较大,使用rm –rf删除即可.   find / -size +10 ...