c - 指向常量指针的双指针
问题描述
嘿,有人能告诉我为什么在这个例子中会出现值 11 11,如果我理解正确的话,主块中的 p 是指向 Integer 的常量指针,这意味着我无法更改其地址的值我怎么能这样做在功能 foo through
#include <stdio.h>
int j = 11;
void foo(int **);
int main()
{
int i = 10;
int *const p = &i;
foo(&p);
printf("%d\n", *p);
}
void foo(int **p)
{
*p = &j;
printf("%d\n", **p);
}
解决方案
大多数编译器,包括 clang 和 gcc,都会对您的代码片段做出反应,并发出类似这样的警告。
const int *
作为参数传递int *
会丢弃限定符
这意味着编译器会发现您违反了指针的恒定性。尽管抱怨,编译器会尝试补偿。编译器将忽略const
您声明中的修饰符p
. 运行时的有效类型p
将是 mutable 的类型int *
。
此行为不是任何 C 标准的一部分。严格来说,const
就像你对编译器做出的承诺,你不会修改任何东西。这个承诺允许对机器代码进行某些优化,允许编译器假设某些值永远不会改变。当你通过隐式类型巧妙地违反const
承诺时铸件转换,更天真的(但在技术上仍然兼容)编译器可能会生成遇到分段错误或其他问题的机器代码,因为您背叛了恒定性的假设。
现代编译器总是检查const
事物是否真的是恒定的。如果不是,那么编译器会“丢弃限定符”,这意味着它们会推断出你并不是真的想说const
. 大多数编译器还推断您确实是指const
如果您从不更改变量的值,无论您是否将其声明为常量。
延伸阅读
推荐阅读
- makefile - 创建共享库链接时的 Makefile 依赖项
- maven-plugin - Maven/Jacoco - 在成功的测试和 jacoco 数据文件合并后,如何获得合并报告?
- r - R中用于工作目录的可选参数解析
- php - Laravel 在 PHP 一般错误:1366 Incorrect integer value
- web-crawler - 指向 HdfsBolt 的 URL 内容
- symfony - 无法使用 SF2 表单删除具有多对多相关对象的实体
- swagger - 在示例值中隐藏字段,但不在 Swagger UI 中的请求正文模型中
- javascript - 如何将jQuery中的输入类型传递给ajax
- google-app-engine - 部署“cron.yaml”需要什么 IAM 角色?
- ios - 如何获得 2 个 cv::Mat 对象之间的绝对差异