首页 > 其他分享 >初识C数据结构之“*”和“&”(指针、解引用、取地址、引用)

初识C数据结构之“*”和“&”(指针、解引用、取地址、引用)

时间:2023-07-25 21:48:32浏览次数:47  
标签:num int 地址 初识 引用 printf 数据结构 指针

  这天小阿杰又在看C数据结构——

  顺序表中几个传参的小小的内容引起了小阿杰大大的疑惑:(教材为严蔚敏老师的《数据结构(C语言版 第2版)》)

      

可怜的小阿杰当时只知道&取地址……后来查阅资料才对其中略知一二,那咱们下面就来唠唠。

顺便提一下,引用&只在C++中有,C语言中并没有什么引用&,只有取地址&,此处应为演示方便而使用

  首先说这个指针取地址,示例如下:

1 int main() {
2     int num = 3;
3     int* p ;                //声明一个指针变量p
4     p= #           // 将变量num的地址取出来,存到指针p中
5     printf("%d 的地址是 %p\n", num, p);
6     return 0;
7  }

输出:

3 的地址是 0x7ffeefbff3ac

  然后看这个解引用,先上示例:

1 int main(){
2     int num = 7;  
3     int* p = #  
4     printf("数值%d所在的地址是 %p\n", num, p);  
5     printf("指针p指向的地址为 %p , 该地址上保存的值为%d\n", p, *p);  
6     *p = 100;  
7     printf("指针p指向的地址为 %p , 该地址上保存的值为%d\n", p, num);  
8     return 0;  
9 }

结果:

数值7所在的地址是 0x7ffeefbff3b8
指针p所指向的地址为 0x7ffeefbff3b8 , 该地址上所保存的值为7
指针p所指向的地址为 0x7ffeefbff3b8 , 该地址上所保存的值为100

其实这里*p和num等价的,个人认为这个“解引用”也许改叫“取值”会更形象一点(),这样的操作,直接顺着地址修改了原本的值,有点“顺藤摸瓜”的意思嘿嘿嘿。

插一句嘴,也可以让指针p指向别的变量的地址,比如:

1 int main(void)  
2 {  
3     int num = 7, another = -5;  
4     int *p = #  
5     p = &another;  
6     printf("%d\n", *p);//此时p指向了another,所以输出了another的值,即-5  
7     return 0;  
8 }  

  这时候咱们来介绍以下引用,最简单来说,“引用”就是起别名,我们来看例子:

 1   int main()  
 2 {  
 3     int val = 7, val2 = 999;  
 4     int &refval = val, &refval2 = val2; //引用必须要初始化,使其绑定到一个变量上  
 5     //修改引用的值将改变其所绑定的变量的值  
 6     refval = -12;  
 7     printf("%d %d\n", val, refval);//-12,refval的值和val一样  
 8       
 9     //将引用b赋值给引用a将改变引用a所绑定的变量的值,  
10     //引用一但初始化(绑定),将始终绑定到同一个特定对象上,无法绑定到另一个对象上  
11     refval = refval2;  
12     printf("%d %d\n", val, refval);//999  
13     return 0;  
14 }  

其结果为:

-12 -12
999 999

小阿杰这里有个形象恰当的比喻(bushi),比方说你有一个全名,还有一个昵称,有人骂你,不管骂的是你的全名还是昵称,被骂的(骂这个动作的承受对象)都是你本人。

(没有冒犯,纯属举例,如果要骂的话,各位读者大大就骂小阿杰吧qaq) 

 

  到这里的话,基本的知识我们就了解了,那回归我们的正题,对于前面图片中的那个“时隐时现”的“&”,我们又该如何理解呢?

 

  对于 SqList&L 这样的函数参数,它使用了引用传递方式。这意味着函数内部对参数的修改会影响到函数外部传入的实参。修改参数的操作可以直接影响到原始的数据。

 

  而对于 SqList L 这样的函数参数,它使用了值传递方式。这意味着函数内部对参数的修改不会影响到函数外部传入的实参。函数会对参数进行一次拷贝,并在函数内部操作该拷贝的副本,而不是直接修改原始数据。

下面咱们来看示例:

 1 #include <stdio.h>
 2 
 3 typedef struct {
 4     int data[5];
 5     int length;
 6 } SqList;
 7 
 8 // 使用引用传递修改参数
 9 void modifyByReference(SqList& L) {
10     L.length = 0;
11     for (int i = 0; i < 5; i++) {
12         L.data[i] = i;
13     }
14 }
15 
16 // 使用值传递修改参数的副本
17 void modifyByValue(SqList L) {
18     L.length = 0;
19     for (int i = 0; i < 5; i++) {
20         L.data[i] = i;
21     }
22 }
23 
24 int main() {
25     SqList myList = {{1, 2, 3, 4, 5}, 5};
26     
27     // 使用引用传递修改
28     modifyByReference(myList);
29     printf("Modified by reference: ");
30     for (int i = 0; i < myList.length; i++) {
31         printf("%d ", myList.data[i]);
32     }
33     printf("\n");
34     
35     // 使用值传递修改副本
36     modifyByValue(myList);
37     printf("Modified by value: ");
38     for (int i = 0; i < myList.length; i++) {
39         printf("%d ", myList.data[i]);
40     }
41     printf("\n");
42 
43     return 0;
44 }

这样的话我们得到的输出结果是:

Modified by reference: 0 1 2 3 4
Modified by value: 1 2 3 4 5

  可以看到,在使用引用传递时,函数内部对参数的修改直接影响到了函数外部传入的实参 myList。而在使用值传递时,函数内部对参数的修改只会影响到函数内部的副本,不会改变原始的 myList 对象。

  经过这么一番折腾,小阿杰对这个引用&符终于有点眉目了,可以心安理得地摆大烂了嘻嘻嘻。

  那咱们今天就先唠到这里吧,再见(灰灰)!

   参考文章:指针(*)、取地址(&)、解引用(*)与引用(&)_指针取地址_Adenialzz的博客-CSDN博客

        关于被调函数形参:SqList L、SqList &L、SqList *L 的区别_c语言sqlist l_Uncertainty!!的博客-CSDN博客

标签:num,int,地址,初识,引用,printf,数据结构,指针
From: https://www.cnblogs.com/JerryWayne7/p/17579325.html

相关文章

  • iptables——自定义链创建及引用
    当默认链中的规则非常多时,不方便我们管理,此时可以考虑用自定义链。比如将所有针对80端口的web入站规则都写入到IN_WEB自定义链中,将所有针对sshd的出站规则都写入到OUT_SSH自定义链中。创建自定义链#在filter表中创建IN_WEB自定义链iptables-tfilter-NIN_WEB引用自定......
  • 7.25 day2数据结构优化dp
    战绩:100+100+20+54=374T1据lxl说是为了成绩好看加的题,难度大概cspjT1T2朴素dp然后树状数组优化一下T3赛时脑抽链,写了个dp,一直想优化dp,其实贪心就好了,过程更加简洁,优化很显然先将区间剖分成两段端点\(s_i=s_j\)相同的多条线段将区间每个点吸附到离他右边最近的一个线段......
  • 【补充】Python中的参数传递是值传递还是引用传递
    【补充】Python中的参数传递是值传递还是引用传递Python中的参数传递都是copy一份传递过去,由于一切皆对象,传过去的都是地址在Python中又区分可变类型和不可变类型可变类型在函数中修改会影响原始的值不可变类型,不会影响原始的值在Python中,参数传递是按对象引用传递的......
  • 如何构造类似数组的数据结构?
    ..介绍在开始解决数组问题之前,理解并实现类似数组的数据结构是一个很好的实践。本课教您如何实现常见的数组操作,例如插入元素、删除元素、获取元素、求数组长度以及打印数组元素。我们正在建设什么?我们将从头开始构建一个数组,其中包含一些最常见的数组操作,如上所述。我们还将学习如......
  • 2023-07-25 html中引入vue,报错:Vue is not a constructor ==》引用的vue版本不兼容导致
    报错代码:我使用的vue外链https://cdn.jsdelivr.net/npm/vue,该外链引用的是最新的[email protected]版本,而我的vue写法为vue2.0版本的写法,故而不兼容。解决方案:引用指定版本的vue......
  • Java后端01(初识servlet)
    servlet添加依赖坐标(maven)<dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version></dependency>小测试​ 所有请求都会固定携带一个参数(method)代表请求的方式(GET,POST,PUT,D......
  • 初识C语言——7扫雷(低配)
    主程序——text.c:#define_CRT_SECURE_NO_WARNINGS1#include"game.h"game(){ charHide[ACRS][COLS]={'0'}; charShow[ACRS][COLS]={'0'}; //数组初识化 Initialize(Hide,ACRS,COLS,'0'); Initialize(Show,ACRS,......
  • 数据结构优化dp
    滚动数组在dp时经常会发现只有相邻阶段间状态才会有直接联系,在转移方程中的体现形如:只有前\(m\)个阶段能影响当前阶段的状态,因此我们不需要储存下\(n\)个阶段的所有状态,只需要储存\(m\)个阶段的状态,以做到优化存储空间的目的。用这种方法可以将dp某一维干掉,把\(\mat......
  • ts项目引用js文件
    1、template- index.html-head添加:  <script type="text/javascript" src="<%= BASE_URL %>assets/lib/jquery.js"></script>2、types-j-query.d.ts添加: declare module 'jQuery'3、vue.config.js- configureWebpack-e......
  • JavaScript数据结构和算法简述——数组
    为什么先讲数组数据结构可以简单的被分为线性结构和非线性结构。线性结构大致包括:数组(连续存储);链表(离散存储);栈(线性结构常见应用,由链表或数组增删和改进功能实现);队列(线性结构常见应用,由链表或数组增删和改进功能实现);非线性结构大致包括:树;图;其中,数组是应用最广泛的数据存储结构。它被......