C *&的用法

基础知识

C语言中,*&是操作指针的符号。什么是指针呢,首先我们先要了解内存的概念。

一台基本的电脑是由:输入输出设备(键盘、鼠标、显示屏,但是没有他们电脑也是可以工作的)、CPU内存硬盘显卡组成的。

  • CPU:大家都知道它是中央处理器,是电脑的核心,是计算机的大脑。
  • 硬盘:它是记录数据用的,它是一种储存器,准确的说是非易失性储存器,简而言之就是我们的数据能在硬盘中长期保存,不会因为断电而丢失。
  • 内存:其用处和硬盘差不多,但是区别在于它是一种易失性储存器,一旦断电,储存在里面的数据就都将丢失,不过它的速度却比传统的机械硬盘快20多倍,因此存放一些程序要临时用到的变量就非常合适。

我们知道,C语言的变量是存在内存里面的,而内存被分为了好多个基本单位,地址就是赋予每个基本单位的唯一标号。简单的说,一个地址对应了一块小内存。

当我们定义变量时

int a = 10;

这样我们就在内存中开扩了一块空间,并把这块内存中存入数据10。

有前面关于地址的概念之后,我们就能想到,如何读取到该变量的地址呢?

而符号&便是这个含义。

&

取址符号:用于将一个变量的地址取出来。

例子:

#include <stdio.h>

int main()
{
    int a = 10; // 定义一个变量,并赋值为10
    printf("%p",&a); // %p用于打印地址,而后面的&a就是用来取出a的地址的。
}

根据例子,我们便能理解&(取址符号)的含义了。


但是&还有另一个含义,那便是引用

引用,其实我们可以这么理解,它可以是一个变量的别名,也就是说一块内存有两个名字(不是地址,地址只能有一个,我指的是变量名字)。下面的那个例子很好的说明了这一切:

#include <stdio.h>

int main()
{
    int a = 10; // 先定义a变量
    int &b = a; // 把a引用到b来
    // int &c; // 这句话错误,使用引用是必须初始化,指定其引用的对象。
    printf("a = %d, b = %d\n", a, b); // 很显然,他会输出a = 10, b = 10
    a = 20; // 我们对a进行赋值操作
    printf("a = %d, b = %d\n", a, b); // 他输出了a = 20, b = 20
    b = 30; // 同样的,我们在对b进行赋值操作
    printf("a = %d, b = %d\n", a, b); // 他输出了a = 30, b = 30
    /// 这也就说明,a和b是绑定的,动其中的一个,那么另一个一定也会随之改变。
    /// 那么也就可以说b是a的一个别名,另一个名称。
    printf("&a = %p, &b = %p\n", &a, &b); // 输出的地址是一样的
    return 0;
}

注释已经写的很详细了,相信大家一定能看懂的。

而实际上,我们也能这么理解。通过上面的例子的最后一句输出可以看出a变量和b变量同时指向了同一块内存,他们的地址实际上是相同的,所以,我们在对a变量进行更改的时候就是指操作了这块内存的内容,而操作b时,我们动的也是这块内存,所以他们才会表现出这样的效果。

*

取值符号:当我们有了一个地址的时候,我们又想知道这个地址对应的内存里存的是什么呢,那么取值符号就可以达到这个目的了。

下面的例子就能解释这个意思了:

#include <stdio.h>

int main()
{
    int a = 10;
    printf("%d",*&a); // 我们先用&a将a变量的地址取出来,然后我们再在最前面加上*取值符号,这时候输出的便又是我们的数字了。
    return 0;
}

但是这样是不是很没用,感觉特别鸡肋?

所以我将介绍*的另一个用法。

int a = 10;
int* b = &a;

我们之前了解了地址的概念,但是地址本身也是可以存到变量当中的,而b变量便是一个指针变量,用于存放指针(地址)

这样说不好理解,不如这样讲吧。学过变量类型我们知道有char, int, long, float, double等几种常见的类型,那么定义变量时就会开启一块内存空间来储存。那么每种类型也对应着一种类型的内存空间,而int对应的指针变量类型便是int*double对应的则是double*,其实就是在每种类型后面加一个*就行了。

指针类型的变量存的就是地址,所以我们定义指针变量便可以像例子中那么写了。

不过,定义指针变量的方法还有一个,并且我更推荐大家这么写,因为区分度较高:

int a = 10;
int *b = &a; // 推荐使用这种写法
int* c = &a;

其实就是空格的位置变了下。

这样一来,*&就便有了意义。

由于b和c变量存的是a的地址,那么我们用b和c去对啊进行赋值的时候也有些不一样,先要用*对b或c变量进行取值,把a取出来之后才能对a进行赋值操作。详情请看例子。

printf("%p",b); // 由于b存的是a的地址,所以这边就打印了a的地址
*b = 20; // 这句话相当于进行了a = 20;操作
printf("%d",*b); // *b是读取b地址里存的值,也就是a的数值

顺便题下,初学者在学输入语句scanf("%d",&a);时往往无法理解&的含义,而现在应该能懂了吧,人家是取出a的地址,然后用*取出值来修改啊。

在函数中的应用

首先我们先来看个例子吧:

#include <stdio.h>

void func1(int num)
{
    num = 1;
}

void func2(int *num)
{
    *num = 1;
}

void func3(int &num)
{
    num = 1;
}

int main()
{
    int a = 0, b = 0, c = 0;
    func1(a);
    func2(&b);
    func3(c);
    printf("a = %d, b = %d, c = %d\n",a, b, c);
    return 0;
}

咋一看,这个例子想实现的应该是同一个功能,那就是通过函数,把数字变成1。

但实际运行时,他却输出了a = 0, b = 1, c = 1的结果,和预期并不一样啊,在这是为什么呢。

其实,我们观察每个函数的定义时就能发现略有不同了。

首先,我们先看func1的定义:

void func1(int num)
{
    num = 1;
}

它的参数是int num,也就是说它传入的是数值,并把它赋值给了变量num,简单地讲就是我们在main函数传入的a,会把它复制给num,彻彻底底的两个变量啊!
所以说,这个函数并不会改变a的值,顶多也是改变了num这个形式参数的值罢了,并没有动到传入的a这个实际参数。


我们再看看第二个函数:

void func2(int *num)
{
    *num = 1;
}

根据之前学习的*的用法我们知道,这里的num变量是用来存储地址的,也就是说这个函数传入的参数是一个地址

在main方法中,我们传入的是&b,也就是将b进行取址之后传入的。
那么num就便是b的地址了,我们再进行*num = 1;的操作时相当于把在num里的地址进行*取值运算,把b取了出来,在对它进行赋值为1。

这样一来,b的数值就发生了实质性的变化,且num并没有变化。


最后一个函数:

void func3(int &num)
{
    num = 1;
}

这边其实就和之前的引用是一样的了。我们引用main中传入的c,并让num变量也指向c的地址,所以我们再进行num = 1;操作的时候。就把num所指向的地址里的数值进行了修改,也就是修改了c的值。

总结

读完本文大家应该能对C语言里*&有了一个新的理解了,同时我也希望本文能帮助到之前对指针一脸懵逼的初学者。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,546评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,224评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,911评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,737评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,753评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,598评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,338评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,249评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,696评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,888评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,013评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,731评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,348评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,929评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,048评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,203评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,960评论 2 355