| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3229 人关注过本帖
标题:深入指针笔记二
只看楼主 加入收藏
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
以下是引用pangding在2012-7-28 18:13:53的发言:

关于存在栈里的数据,它一定是可写的,这个没法改变。只是编译器会对加了 const 关键字的东西进行审查。任何对之修改的语句,都会产生语法错误,从而保护它的值。但其实你还是可以改动它的值,方法不用我说 有容 自己试试就知道了。
这个 const 只是在语义上保护程序,以免不小心修改逻辑上不能改的值。但不能防止精心设计的修改(即是说并非利用语义,而是在执行过程中修改它)。

大牛说的对 如果挂上调试器 想改什么就改什么

这个const只不过从编程或者说是编译的层面限制了它不能改
2012-07-28 18:20
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
以下是引用LShang在2012-7-28 11:43:22的发言:

跟环境与关吧,TC下随便改

是的,不是所有编译器的行为都是一样的。相同的字面值只有一份,也不是普遍适用的。

授人以渔,不授人以鱼。
2012-07-28 18:27
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
程序区中的只读数据,只是这个进程保护为只读,但不表示操作系统也保护它,别的进程可以尝试写,因为行为不归这个进程管。同样,某些硬件的地址数据,是操作系统保护它而已,对一个不保护硬件的操作系统来说,比如DOS,就可以写,除非硬件电路本身不允许写,就能写进,直至硬件遭到破坏。没有什么是一定的。

TC是DOS下的编译器,DOS不保护硬件,TC也同样不保护,这很正常。保护数据的概念,是多任务系统下的重要观念,然而DOS不是多任务操作系统,DOS的程序员,是没有这种保护概念的,更常见的,恰恰是利用这种直接读写硬件的特性来提升程序性能,TC本身就是以这种行为著名的,其Graphics库直接读写显示卡的内存,所以在Windows中TC被迫改造,无法直接写屏,图形效率大打折扣——效率降低被淘汰事小,观念事大,动辄指向硬件、切入系统底层,对Windows来说都是大忌,学惯了这一套,很难扭转的。这对倾向于深入底层,力图控制机器一切细节的程序员来说,是很值得思考的,某些操作系统,由于本身开放源代码,所以任由程序员操控整个系统,在这方面,获得赞誉,但究竟是否真的好事,看具体应用了。

[ 本帖最后由 TonyDeng 于 2012-7-28 18:50 编辑 ]

授人以渔,不授人以鱼。
2012-07-28 18:35
有容就大
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:东土大唐
等 级:版主
威 望:74
帖 子:9048
专家分:14309
注 册:2011-11-11
收藏
得分:0 
去做了个实验
VS2010下进行的。
main.c文件
程序代码:
#include <stdio.h>
#include <Windows.h>

int main(void)
{   
    const int i = 1;   
    int *p = (int *) &i;

    *p = 99;
    printf("i = %d  VS  *p = %d\n", i, *p);

    system("pause");
    return 0;
}
图片附件: 游客没有浏览图片的权限,请 登录注册


main.cpp文件1


程序代码:
#include <iostream>
#include <Windows.h>
using namespace std;

int main(void)
{   
    system("cls");
    const int i = 1;   
    int *p = (int *) &i;

    *p = 99;
    cout << "i = " << i << " VS ";
    cout << "*p = " << *p << endl;

    system("pause");
    return 0;
}
图片附件: 游客没有浏览图片的权限,请 登录注册


main.cpp文件2
程序代码:
#include <iostream>
#include <Windows.h>
using namespace std;

int test() { return 1; }

int main(void)
{
    system("cls");
   
    const int i = test();   
    int *p = (int *) &i;

    *p = 99;
    cout << "i = " << i << " VS ";
    cout << "*p = " << *p << endl;

    system("pause");
    return 0;
}
图片附件: 游客没有浏览图片的权限,请 登录注册


说明C编译器和C++编译器还是有些不一样。


[ 本帖最后由 有容就大 于 2012-7-28 19:18 编辑 ]

梅尚程荀
马谭杨奚







                                                       
2012-07-28 19:14
有容就大
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:东土大唐
等 级:版主
威 望:74
帖 子:9048
专家分:14309
注 册:2011-11-11
收藏
得分:0 
回复 33楼 TonyDeng
那如果是一个个进程想要保护一个数据 把他存在常量区 会不会在同时就通知操作系统 : 别让别人来修改我要保护的数据! ? 从而操作系统就禁止一切进程妄图去修改它。

梅尚程荀
马谭杨奚







                                                       
2012-07-28 19:37
有容就大
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:东土大唐
等 级:版主
威 望:74
帖 子:9048
专家分:14309
注 册:2011-11-11
收藏
得分:0 
以下是引用pangding在2012-7-28 18:10:07的发言:

大致可以这么理解。程序包括可执行的代码和数据。分别放在程序段和数据段。

一般来说只有程序段的代码是可执行的:这样设计可以使得修改返回地址,以执行一段精心设计的数组内的数据是不可行的。
数据段又可以分为只读的读写的。只读的数据就是只能读不能写,用来存各种常量,包括字符串字面。读写的就用来存那些可以写的。

因为这些数据都包装在可执行文件里,所以只有初始化的数据才写在里面。还没初始化的变量,就说是放在一个叫 BBS 的段里。那个段并不编译到可执行文件里,在执行的时候才开辟内存。
你可以试试,开辟一个很大的全局数组。一个不初始化,另一个比如把第一个元素赋值成1,看看生成的可执行文件大小有没有区别。
程序代码:
#include <stdio.h>

int a[10000000] = {0};


int main(void)
{       
    return 0;
}

--
程序代码:
#include <stdio.h>

int a[10000000];

int main(void)
{  
    return 0;
}



怪了 这两工程的可执行文件大小一样?

梅尚程荀
马谭杨奚







                                                       
2012-07-28 19:42
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:0 
写成 1 呢?
2012-07-28 19:44
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:0 
回复 34楼 有容就大
vs 有优化特性,你写了 const int i = 1 之后,有的时候要访问这个变量值的地方,由于编译器以为它的值不会变,就直接把 1 传过去了,没有访问 i 的值。好像能在哪关这些优化特性来着,不过我对 vs 不是很熟。2010 是不是还这样我也不是很清楚,至少以前是这样的。
2012-07-28 19:49
有容就大
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:东土大唐
等 级:版主
威 望:74
帖 子:9048
专家分:14309
注 册:2011-11-11
收藏
得分:0 
回复 37楼 pangding
哈哈 初始化为0还体现不出来 原来系统就默认没初始化的全局变量为0

改成1后
一个184k  一个45.9M 确实是天渊之别啊 受教了。

[ 本帖最后由 有容就大 于 2012-7-28 19:55 编辑 ]

梅尚程荀
马谭杨奚







                                                       
2012-07-28 19:50
陈艺深13
Rank: 2
等 级:论坛游民
帖 子:22
专家分:11
注 册:2012-7-26
收藏
得分:0 
学习了
2012-07-28 19:53
快速回复:深入指针笔记二
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.024204 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved