当前位置:首页 » 编程软件 » const指针编译

const指针编译

发布时间: 2022-10-25 12:02:07

1. C++的const 与指针的问题

好久没接触C/C++了,我来回复下吧:

consttest*tes确实不能通过tes修改对像的值,如下,编译器将会报错:


voidInput(consttest*tes)

{

tes->i=5;

}

问题出在&取地址符,该符号取了i的地址(注意,不是直接通过test来修改的),所以不会报错,可以将&tes->i分解步骤理解:

  1. tes->i 通过tes取i对象

  2. &(tes->i) 获取该对象的地址

可见并未直接通过tes修改其值

2. const指针 c语言

const 只对它申明的变量负责,且只是在编译时检查,当你把它强制类型转换了就能修改它
你这个编译器有点老,新的编译器在 int *b = &a; 就出错了,原因是这里有个从const int *到int *的隐式转型。

另,C语言的指针很灵活,但使用它需要特别注意安全,像这样的做法也能直接把a改了:
const int a=3;
*(int *)a = 5;

3. 如何利用指针改变const类型的值

#include <iostream>
using namespace std;
void main()
{
const int a=10;
cout<<a<<endl;
int *q=(int*)(&a);
int t=(int)a;
int *p=&t;
*p=6;
*q=5;
cout<<a<<endl;
cout<<*q<<endl;
cout<<*p<<endl;
}

看看这个程序把,然后下断点,调试下,调试的过程中你会发现用指针访问的是表示修改了,但是变量名的依然还是原来的值..
其实,你应该知道一点,使用了强制转换的地方,最后都为它对应生成了一个临时变量,这个时候,指针也指向了这个临时变量,然后你用指针修改仅仅修改了的都是这些临时变量的值,并没有作用到const变量a,因此,你通过指针输出是改变了的值,但是通过变量名则还是原来的值

所以说,你以前所做的修改仅仅是停留在临时变量上的修改(就是假修改,误导了你认为自己修改了const类型的值),对于const类型的变量,你是永远也不能修改的,否则,定义const就没有安全性可言了

现在应该知道为什么了把...如果还有问题
可以发消息给我

晕...还是同一个帖子,看错了
刚调试了下,的确是改了,但是可能就是const的作用把,至于为什么,我现在也不得而知,可能不能很好的帮到你

补充:首先,收回上面的回复...上面的回复是错的
最后修改下,给个权威答案
#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而不是变量值

4. const指针的用法

有两种形式:

1.指向const的指针
使用指针定义的技巧,正如任何复杂的定义一样,是在标识符的开始处读它并从里向外读。
const指定那个“最靠近”的。这样,如果要使正指向的元素不发生改变,我们得写一个像这
样的定义:
const double* point;
从标识符开始,是这样读的:“x是一个指针,它指向一个const int。”这里不需要初始化,因为
说x可以指向任何东西(那是说,它不是一个const),但它所指的东西是不能被改变的。

2.const指针
使指针本身成为一个const指针,必须把const标明的部分放在*的右边,如:
int d=1;
int* const x=&d;
现在它读成“ x是一个指针,这个指针是指向i n t的const指针”。因为现在指针本身是const指针,
编译器要求给它一个初始化值,这个值在指针寿命期间不变。然而要改变它所指向的值是可以
的,可以写* x = 2;
也可以使用下面两种合法形式中的任何一种形式把一个const指针变为一个const对象:
int d=1;
const int* const x=&d; // (1)
int const* const x2=&d; // (2)
现在,指针和对象都不能改变。
一些人认为第二种形式更好。因为const总是放在被修改者的右边。但对于特定的代码类型
来讲,程序员得自己决定哪一种形式更清楚。

你的并没有错啊,要错也是在*号后加一个空格吧

5. C语言中const是什么意思。。。

const 推出的初始目的,正是为了取代预编译指令,消除它的缺点,同时继承它的优点。

const关键字使用非常的灵活,这一点和php差别很大,php中const用来在类中定义一个常量,而在c中,const因位置不同有不同的作用,因情景不同有不同的角色,使用起来也是非常的灵活。

一、const用来修饰普通的变量(指针变量除外)的时候,const type name 和 type const name 这两种形式是完全等价的,都表示其是常量,不能进行修改。

二、const用来修饰指针变量的时候,分为以下四种情况

1、const type *name :这种情况下,const修饰的指针变量name所指向的type类型对象,也就是说指向的这个对象是不能进行修改的,因为其是常量,而指针变量确实可以进行修改的。

2、type const *name :这种情况下,const修饰的指针变量name所指向的type类型对象,意思完全同上,只是颠倒了以下顺序。

3、type * const name :这种情况下,const修饰的指针变量name,也就是说这个指针变量的值是不能进行修改的,但是指针变量所指向的对象确实可以修改的。

4、const type * const name :这种情况下,const修饰的指针变量name以及指针变量name所指向的对象,也就是说这个指针变量以及这个指针变量所指向的对象都是不能进行修改的。

(5)const指针编译扩展阅读

使用const在一定程度上可以提高程序的安全性和可靠性。另外,在观看别人代码的时候,清晰理解const所起的作用,对理解对方的程序也有一定帮助。另外CONST在其它编程语言中也有出现,例如Pascal、C++、PHP5、B#.net、HC08 C、C#等。

在c中,对于const定义的指针,不赋初值编译不报错,int* const px;这种定义是不允许的。(指针常量定义的时候对其进行初始化)int const *px;这种定义是允许的。(常指针可以再定义的时候不初始化)

但是,在C++中int* const px;和const int* const px;会报错,const int* px;不报错。必须初始化指针的指向int* const px = &x;const int* const px=&x;强烈建议在初始化时说明指针的指向,防止出现野指针!

6. const指针问题 int s(1),t(2); int * const p1 = &s; (int*)p1 = &t; //这是什么写法为什么可以编译过呢

int * const p1是一个不可以修改 s 内存的值的指针,但是指针本身的指向可以修改,所以 第二个语句就是让他在指向 t 变量的内存。

7. 怎么用const

C++中const用法总结
作者JuKevin
1. const修饰普通变量和指针
const修饰变量,一般有两种写法:
const TYPE value;
TYPE const value;
这两种写法在本质上是一样的。它的含义是:const修饰的类型为TYPE的变量value是不可变的。
对于一个非指针的类型TYPE,无论怎么写,都是一个含义,即value只不可变。
例如:
const int nValue; //nValue是const
int const nValue; // nValue是const
但是对于指针类型的TYPE,不同的写法会有不同情况,例如:
A. const char *pContent;
B. char * const pContent;
C. char const *pContent;
D. const char* const pContent;
对于前三种写法,我们可以换个方式,给其加上括号
A. const (char) *pContent;
B. (char*) const pContent;
C. (char) const *pContent;
这样就一目了然。根据对于const修饰非指针变量的规则,很明显,A=C.
- 对于A,C, const修饰的类型为char的变量*pContent为常量,因此,pContent的内容为常量不可变.
- 对于B, 其实还有一种写法: const (char*) pContent;
含义为:const修饰的类型为char*的变量pContent为常量,因此,pContent指针本身为常量不可变.
- 对于D, 其实是A和B的混合体,表示指针本身和指针内容两者皆为常量不可变
总结:
(1) 指针本身是常量不可变
(char*) const pContent;
const (char*) pContent;
(2) 指针所指向的内容是常量不可变
const (char) *pContent;
(char) const *pContent;
(3) 两者都不可变
const char* const pContent;
还有其中区别方法:
沿着*号划一条线,
如果const位于*的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;
如果const位于*的右侧,const就是修饰指针本身,即指针本身是常量。
2. const修饰函数参数
const修饰函数参数是它最广泛的一种用途,它表示函数体中不能修改参数的值(包括参数本身的值或者参数其中包含的值)。它可以很好
void function(const int Var); //传递过来的参数在函数内不可以改变(无意义,因为Var本身就是形参)
void function(const char* Var); //参数指针所指内容为常量不可变
void function(char* const Var); //参数指针本身为常量不可变(也无意义, 因为char* Var也是形参)
参数为引用,为了增加效率同时防止修改。
修饰引用参数时:
void function(const Class& Var);//引用参数在函数内不可以改变
void function(const TYPE& Var); //引用参数在函数内为常量不可变
3. const 修饰函数返回值
const修饰函数返回值其实用的并不是很多,它的含义和const修饰普通变量以及指针的含义基本相同。
(1) const int fun1() 这个其实无意义,因为参数返回本身就是赋值。
(2) const int * fun2()
调用时 const int *pValue = fun2();
我们可以把fun2()看作成一个变量,那么就是我们上面所说的1.(1)的写法,即指针内容不可变。
(3) int* const fun3()
调用时 int * const pValue = fun2();
我们可以把fun2()看作成一个变量,那么就是我们上面所说的1.(2)的写法,即指针本身不可变。
4. const修饰类对象/对象指针/对象引用
const修饰类对象表示该对象为常量对象,其中的任何成员都不能被修改。对于对象指针和对象引用也是一样。
const修饰的对象,该对象的任何非const成员函数都不能被调用,因为任何非const成员函数会有修改成员变量的企图。
例如:
class AAA
{
void func1();
void func2() const;
}
const AAA aObj;
aObj.func1(); ×
aObj.func2(); 正确
const AAA* aObj = new AAA();
aObj->func1(); ×
aObj->func2(); 正确
5. const修饰成员变量
const修饰类的成员函数,表示成员常量,不能被修改,同时它只能在初始化列表中赋值。
class A
{

const int nValue; //成员常量不能被修改

A(int x): nValue(x) {}; //只能在初始化列表中赋值
}
6. const修饰成员函数
const修饰类的成员函数,则该成员函数不能修改类中任何非const成员函数。一般写在函数的最后来修饰。
class A
{

void function()const; //常成员函数, 它不改变对象的成员变量. 也不能调用类中任何非const成员函数。
}
对于const类对象/指针/引用,只能调用类的const成员函数,因此,const修饰成员函数的最重要作用就是限制对于const对象的使用。
7. const常量与define宏定义的区别
(1) 编译器处理方式不同
define宏是在预处理阶段展开。
const常量是编译运行阶段使用。
(2) 类型和安全检查不同
define宏没有类型,不做任何类型检查,仅仅是展开。
const常量有具体的类型,在编译阶段会执行类型检查。
(3) 存储方式不同
define宏仅仅是展开,有多少地方使用,就展开多少次,不会分配内存。
const常量会在内存中分配(可以是堆中也可以是栈中)。

我这里有个更加详细的,但这里贴不下了,如果需要,给我邮箱,发给你

8. const指针问题

p1指向的是一个常量“abcd”,常量是不允许修改的,所以会报错。p2指向的是一个字符数组,数组是允许修改的。
还有cp1和cp2是常量指针,是指本身是常量,赋地址值给cp1,cp2后不能改cp1cp2的值了,但是他们所指的区域能否更改,要看那个区域是否允许更改。这题就是p1是常量不允许更改,p2是数组允许更改。

热点内容
同时修改多台服务器管理地址工具 发布:2025-05-16 09:20:36 浏览:420
什么配置就能玩地平线 发布:2025-05-16 09:13:46 浏览:82
python旋转图片 发布:2025-05-16 09:13:40 浏览:638
少女前线防检测脚本 发布:2025-05-16 08:59:07 浏览:728
编译器对系统的依赖 发布:2025-05-16 08:37:29 浏览:711
javamap数组 发布:2025-05-16 08:37:28 浏览:451
移动光猫如何自行修改密码 发布:2025-05-16 08:20:15 浏览:125
作为基线存储 发布:2025-05-16 08:15:22 浏览:859
安卓怎么关闭手机应用推荐 发布:2025-05-16 08:03:38 浏览:930
sql内置函数 发布:2025-05-16 08:03:34 浏览:923