引用做什么

本文介绍了PHP引用的使用,包括用两个变量指向同一内容、在函数和new运算符中使用引用。还提到不用&运算符会导致对象拷贝,&new语句中@运算符无效,这是Zend引擎的限制。此外,阐述了引用传递变量和引用返回的相关内容。


PHP 的引用允许你用两个变量来指向同一个内容。意思是,当你这样做时:


<?php
$a =& $b
?> 


这意味着 $a 和 $b 指向了同一个变量。
注: $a 和 $b 在这里是完全相同的,这并不是 $a 指向了 $b 或者相反,而是 $a 和 $b 指向了同一个地方。


同样的语法可以用在函数中,它返回引用,以及用在 new 运算符中(PHP 4.0.4 以及以后版本):


<?php
$bar =& new fooclass();
$foo =& find_var ($bar);
?> 

 

注: 不用 & 运算符导致对象生成了一个拷贝。如果你在类中用 $this,它将作用于该类当前的实例。没有用 & 的赋值将拷贝这个实例(例如对象)并且 $this 将作用于这个拷贝上,这并不总是想要的结果。由于性能和内存消耗的问题,通常你只想工作在一个实例上面。

尽管你可以用 @ 运算符来关闭构造函数中的任何错误信息,例如用 @new,但用 &new 语句时这不起效果。这是 Zend 引擎的一个限制并且会导致一个解析错误。

引用做的第二件事是用引用传递变量。这是通过在函数内建立一个本地变量并且该变量在呼叫范围内引用了同一个内容来实现的。例如:


<?php
function foo (&$var)
{
    $var++;
}

$a=5;
foo ($a);
?> 


将使 $a 变成 6。这是因为在 foo 函数中变量 $var 指向了和 $a 指向的同一个内容。更多详细解释见引用传递。

引用做的第三件事是引用返回。

### 什么是“解引用”(Dereference)? 在 C 语言中,**解引用** 是指通过一个指针访问它所指向的内存中的值。 --- #### 🔍 简单定义: > **解引用就是“通过指针拿到它指向的数据”这个操作。** 使用 `*` 运算符来实现。 --- ### ✅ 示例代码说明 ```c int x = 10; int *p = &x; // p 是一个指针,保存了 x 的地址 // 解引用:通过 p 获取 x 的值 printf("%d\n", *p); // 输出 10 —— 这里的 *p 就是“解引用” ``` - `p` 存的是地址(比如 `0xffff8000`) - `*p` 表示:去那个地址里读取数据 → 就是 `10` - 这个过程就叫 **解引用** --- ### 🧠 类比理解 你可以把指针想象成“遥控器”,而它指向的变量是“电视”。 - 遥控器本身不能换台; - 但你按“解码”按钮(即 `*p`),就能控制电视; - 如果电视坏了或没接电(目标内存无效/为空),那你一按就会出问题! 所以: > ❗ **如果指针是 NULL(空指针),你还去解引用它(*p),程序就会崩溃!** --- ### 💥 错误示例:空指针解引用 ```c int *p = NULL; printf("%d\n", *p); // 崩溃!试图访问地址 0x0 处的数据 ``` 这就是常说的 **段错误(Segmentation Fault)** 或内核中的 **Oops**。 --- ### 📌 在你的原始问题中发生了什么? 你有这样一行代码: ```c struct touchpanel_data *ts = spi_get_drvdata(tcm_hcd->s_client); ``` 这句代码中: - `tcm_hcd->s_client` 实际上等价于 `(*(tcm_hcd)).s_client` - 它先访问 `tcm_hcd` 指向的结构体成员 `s_client` - 所以这里对 `tcm_hcd` 了一次 **解引用** 但如果 `tcm_hcd` 是 `NULL`,这一行就会导致 **系统崩溃** 而你在之后才判断: ```c if (tcm_hcd == NULL) { return; } ``` 这就成了: > ❌ 先解引用 → 再检查是否为空 > 相当于“先踩油门再看有没有车”—— 危险! --- ### ✅ 正确顺序应该是: ```c if (tcm_hcd == NULL) { return; // 先检查,避免后续解引用 } // 此时才能安全地使用 tcm_hcd->xxx struct touchpanel_data *ts = spi_get_drvdata(tcm_hcd->s_client); ``` --- ### ✅ 总结:“解引用”的关键点 | 概念 | 说明 | |------|------| | **指针** | 存储某个变量的内存地址,如 `int *p = &x;` | | **解引用** | 使用 `*p` 获取指针指向的值 | | **空指针解引用** | 对 `NULL` 指针进行 `*p` 操作 → 导致程序崩溃 | | **如何避免** | 在每次解引用前,务必检查指针是否为 `NULL` | --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值