为了账号安全,请及时绑定邮箱和手机立即绑定

以下这个问题比较模糊,是关于const常量的问题?

以下这个问题比较模糊,是关于const常量的问题?

千巷猫影 2021-06-09 11:07:39
如下代码:const a=2;int *p;p=(int *)&a;*p=1;cout<<a<<" "<<*p<<endl;输出竟是2 1;谁解释一下?在内存中a地址中内容的确被改,但输出时总是原值...我少写了个int.是 const int a=2;我就是看直接改不行,好不容易才想到的办法.我查看内存发现a地址里的内容确实被改掉了.但a的值却就是不变,那a的值到底存在哪啊?还是用的宏定义替换的方法?我以前这么作过:int a=2;const int *p=&a;int *q;q=(int*)p;*q=1;然后输出*p是1啊 .
查看完整描述

2 回答

?
万千封印

TA贡献1891条经验 获得超3个赞

我来解释下把,算了,直接给你写个程序让你看看把
const int a=20;
const int *p=&a;
与下面的对比
const int a=20;
int *p=&a;

现在来说一下,两种情况,a都是常量,所以不管在哪一种情况下
a的值都不会改变的,而对于两个指针变量,就不相同了,一个是const指针
而另外一个是非const指针,也就是说对于const指针的那种情况,其指针变量p的值与其指向的内容a都不可改变,因为他们都是const修饰的,而对于非const指针,则表示其指针变量p的值是可以改变的,但是其指针变量所指向的内容a依然是不可以改变的,所以你再看看你的那个程序了

const a=2; //你没加类型难道编译器没报错?
int *p;
p=(int *)&a; //这里要注意啊,&a的类型是const int*,而p是int*的,你在这里进行的类型的强制转换,将const int*转换成了int*,否则不能赋值的
*p=1;
cout<<a<<" "<<*p<<endl;
你可以对比下下面的程序
#include <iostream>
using namespace std;
int main()
{
const int a=2;
int *p;
p=&a; //会报错
*p=1;
cout<<a<<" "<<*p<<endl;
}

下面的

#include <iostream>
using namespace std;
int main()
{
const int a=2;
int *p;
p=(int*)&a; //不会报错
*p=1;
cout<<a<<" "<<*p<<endl;
}

有问题可以发消息给我

补充:
也不知道之前是怎么回复你的,不过,现在,收回上面的回复...
最后修改下,给个权威答案
#include<stdio.h>
int main()
{
const int a=3;
int *p=(int *)&a;
*p=6;
printf("%d\t%d\n", *p , p );
printf("%d\t%d\n", a , &a );
return 0;
}
你把它分别放到C++编译器上和C编译器上运行这段代码看看结果如何.如果你用C++编译器编译上述代码,那么这个问题的原因是编译器在编译时自动优化了const值,造成你的code变成 printf("%d\t%d\n", 3 , &a );
我在这里瞎插一句把,感觉就有点像#define N 10
然后用10替换了N的意味把,虽然这样说不准确
但就这样理解把,的确是可以修改,只是编译器优化的缘故而导致输出的和想象的不一样了

这就是权威答案,如果你学过汇编,你可以上汇编试试
如果你用C语言编译器,你会发现,输出的都是6,因为C语言编译器并没有对它进行优化

底下是汇编代码:

INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

CONST SEGMENT
$SG3833 DB '%d', 09H, '%d', 0aH, 00H
ORG $+1
$SG3834 DB '%d', 09H, '%d', 0aH, 00H
CONST ENDS
PUBLIC _main
EXTRN _printf:PROC
; Function compile flags: /Odtp
_TEXT SEGMENT
_a$ = -8 ; size = 4
_p$ = -4 ; size = 4
_main PROC
; File c:\documents and settings\hwp\桌面\test.cpp
; Line 3
push ebp
mov ebp, esp
sub esp, 8
; Line 4
mov DWORD PTR _a$[ebp], 3
; Line 5
lea eax, DWORD PTR _a$[ebp]
mov DWORD PTR _p$[ebp], eax
; Line 6
mov ecx, DWORD PTR _p$[ebp]
mov DWORD PTR [ecx], 6
; Line 7
mov edx, DWORD PTR _p$[ebp]
push edx
mov eax, DWORD PTR _p$[ebp]
mov ecx, DWORD PTR [eax]
push ecx
push OFF
SET $SG3833
call _printf
add esp, 12 ; 0000000cH
; Line 8
lea edx, DWORD PTR _a$[ebp]
push edx
push 3
push OFFSET $SG3834
call _printf
add esp, 12 ; 0000000cH
; Line 9
xor eax, eax
; Line 10
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END

看到了没有....这里
; Line 8
lea edx, DWORD PTR _a$[ebp]
push edx
push 3
push OFFSET $SG3834
call _printf
add esp, 12 ; 0000000cH

直接是push 3
意思说直接输出的是数值3而不是变量值



查看完整回答
反对 回复 2021-06-15
?
红颜莎娜

TA贡献1842条经验 获得超12个赞

const a=2;
int *p;
p=(int *)&a; //使用了强制转换,强制将const int * 转换成 int * ,但这种强制转换只是暂时的
*p=1;
cout<<a<<" "<<*p<<endl; //*p 实际上是

经编译
int a=2;const int *p=&a;int *q;q=(int*)p;*p=1;
有错,其实不编译也知道,因为p被定义为指向类型为const int 的指针,当进行*p=1时,其实是给常量赋值,当然会有错。

你可以这么理解 const int *p,“自己为指向const int ”



查看完整回答
反对 回复 2021-06-15
  • 2 回答
  • 0 关注
  • 235 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信