从语句 char* p="test" 说起

来源:互联网 发布:painter中文版下载mac 编辑:程序博客网 时间:2024/06/06 16:53
从语句 char* p="test" 说起
 
陈皓
 
 
我相信,使用C/C++多年的人对下面这个字符串赋值语句都不会陌生吧。
 
              char* p = "test";
 
同时,我也相信,各位在使用这种语句后吃过很多苦头也不少吧?只要你想利用指针p来改变字符串的内容,你的程序都会得到一个让你颜面尽失一个内存非法操作。比如,下面的这些语句:
 
              p[0] = 's';
              strcpy(p, "haoel");
 
原因就在于,char* p = "test"; 这个声明,声明了一个指针,而这个指针指向的是全局的const内存区const内存区当然不会让你想改就改的。所以,如果你一定要写这块内存的话,那就是一个非常严重的内存错误。另,之所以加粗“全局const内存区”,是强调一下,如果你不信的话,你可以试试下面这段代码,看看p1p2的地址是不是一样的。
 
              char* p1 = "anything";
              char* p2 = "anything";
              printf(“ p1=%x, p2=%x /n”, p1, p2);
 
我想这应该是一个众所周知的问题吧。取而代之的,应该是使用数组来做初始化声明。如:char str[] = “hello world”; 如果现在还有哪本书中的C的示例采用了使用const字符串初始化指针的这种方式,那么你就可以把那本书撕了,如果这本书是C++的书话,那么你应该把这个作者和这个出版社告上法庭,因为你不应该容忍这种学术骗子。如果你的部门的开发人员还有人写出这种代码的话,如果他是C程序员,我想你可以在打过他的屁股后告诉他下不为例,如果他是一个C++程序员的话,我想你可以怀疑他是否有资格做一个C++程序员了。
 
       至于你问我为什么要对学C++的人那么苛刻,那是因为学过C++的人都知道C++中的const关键字的有着什么样的权力,你也应该知道C++const有着无比的照顾和关爱,几乎所有关于C++的书都会提到const这东西。所以,如果作为一个C++的程序员来说,如果你不知道的话,那就太说不过去了。
 
       我们知道,双引号引起来的字符串是const的,所以,在C++的世界中,你应该进行如下的声明才比较稳妥:
             
              const char *p = "test";
 
这样,当你修改这个字符串的内容时,编译器会给你一个错误而导致你的程序编译不通过,从而不会产生运行时的内存错误。
 
       可问题是,像C++这种对类型要求很严格的语言来说,为什么它在编译诸如char *p="test" 程序的时候不出错,甚至连个警告都没有(g++vc++7)?难道这是他的一个bug?我想,这应该是对古老的C的一个向下兼容。因为,在C的世界中,这种用法太多了。
 
C++中,比如:函数的参数和异常的捕获都存在这种问题,如下所示:(因编译器而定,在gcc 3.4.3版中,下例中的异常示例不能被捕获,但VC++6中却可以被捕获)
 
       func( char* p) { }   // 以这种方式调用函数func(“abc”);
      
       try { thow “exception”; } catch (char* p) { }
 
       这些都是C++编译器默认了可以把const char* 转成 char* 的罪行,无疑会对大家是一个误导。甚至让人无所畏惧地走入其中,并自以为走入了正途。这样看来,这种向下兼容的C++标准,就显得有点误人不浅了
 
       不过好在,C++标准委员会早已意识到了这一点。这个C++feature被定义为了“Deprecated Feature”,即“不被建议使用的特性”。意思就是,在将来,这种特性将被从C++中移出,于是,你目前的这种程序将无法在新的C++编译器上编译通过。对于程序的可移植性来说,我们今天所写的代码尤其要注意这些“Deprecated Feature”。
 
       据我所知,目前C++中被列为“Deprecated Feature”如下所示(可能不准确,请大家指正)下面的这些feature都已被C++标准委员会订为废除featrue了。
 
一、           隐晦的字符串的const转换。

char *p = "test";
w_char *pw = L"test";

       把一个const的字符串类型转成non-const的。包括指针和数组。
 
二、           隐晦的类型声明。

func() {}   //函数的隐晦返回类型是int
static num;    //变量的隐晦类型是int
       这种featureC89中还可以使用,但在C99C++中都被去除了。(gcc 3.4版本对于这种声明会给出编译错误,而VC++6.0会认为这是合法的程序)
 
三、           布尔变量的累加操作。
bool isConn = false;
isConn++;          //这个操作会把isConn变为true
就目前而言,几乎所有的编译器都认可这种操作,但这种用法也是不被建议的,终有一天会被取消。
 
四、           更改父类成员的存取权限。
 
class B
{
    protected:
        int i;
};
 
class D : public B
{
     public:
        B::i; //这种方式可能大家很少看到。
};
 
       对于这种语法,子类重新暴露了父类的私有成员。这会带来很大的安全性问题。目前而言,这个feature对于所有的编译器来说应该都是可以编译通过的(连个Warning都没有)。但这个feature也是要被废除的。
 
五、           文件中域的static声明
 
static int i;
static void func()
 
       据说,这种旧的在C中的为了实现其作用域在本文件中的feature在未来的C++中也要被取消。
 
 
文章到这里应该结束了,在结束之前,让我再给大家共享一个有趣的关于const的例子(在网上看到的)
 
    const int a = 1;
    int *p = const_cast(&a);
    *p = 2;
 
    cout << “value a=”<< a << endl;
    cout << “value *p=” <<*p << endl;
    cout << “address a=” <<&a << endl;
    cout << “address p=” <

这段代码输出的结果如下:
 
value a=1
value *p=2
address a=0xbff1d48c
address p=0xbff1d48c
 
地址都是一样的,可值为什么不一样呢?呵呵。这个问题看起来有点“学术味”过浓,不过是个好例子,可以让你知道C++的一些用法和一些原理。有以下几个方面大家可以考虑一下:
1)const int a = 1是不是和宏有点像,会不会被编译器优化了?
2)去修改一个const的值,本来应该是不对的。这可能会是向旧的C兼容。是否会让编译器产生未知行为?
 
所以,这个示例也告诉我们,我们应该遵循C++中的constnon-const的语义,任何想要破坏这个语义的事情都会给我们带来未知的结果。
 
(转载时请注明作者和出处。未经许可,请勿用于商业用途)
更多文章请访问我的Blog: http://blog.csdn.net/haoel



原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 在转转上卖东西下单了想取消怎么办 丈夫的前儿子偷了我的钱我该怎么办 从日本寄的邮包被海关扣下了怎么办 卖家要求退货寄过去的货坏了怎么办 寄快递发货单丢了货发出去了怎么办 酷派手机电源键坏了开不了机怎么办 红米4a进水后开机就黑屏了怎么办 红米1s进水后开机了黑屏了怎么办 魅族手机已锁定魅族账号忘了怎么办 魅族5糸统升级后开不了机了怎么办 如果别人用电脑登了你的微信怎么办 消逝的光芒买错了买的普通版怎么办 在人人车卖了个车买家不过户怎么办 应用锁密码和密保问题都忘了怎么办 不小心在微信公众号发了消息怎么办 微信漂流瓶不能用了被投诉了怎么办 货物少了拉货的不承认少了怎么办 寄的快递号码留错了已经寄走怎么办 网购快递放在单位门卫室丢了怎么办 顺丰生鲜速配时效内食物坏了怎么办 竟尤理财跑路怎么办钱追的回来吗 博贝游戏用支付宝提不了现该怎么办 陌陌钱包没绑支付宝就体现了怎么办 鞋子让太阳晒的一只大一只小怎么办 美团不让上饿了么平台们商家怎么办 在汇通信诚租贷款买车被骗后怎么办 我的网银账户里的钱被盗了怎么办 老赖跑到国外去了还换了国籍怎么办 内裤把屁股两边磨得又肿又疼怎么办 京东在面临供货商不供货时怎么办的 打错的消息想撤回但按了删除怎么办 顺丰快递寄的黄皮和荔枝坏了怎么办 我发快递写错地址备签收不还怎么办 新买的床上四件套用着全身痒怎么办 华为畅玩6x锁屏密码忘了怎么办 我在淘宝上买了货不发货咋怎么办 在快递公司寄的东西丢了我该怎么办 不小心给了快递员子一个差评怎么办 不小心用发霉了的杯子喝了水怎么办 唐三复活了小舞失去的魂环怎么办了 我该怎么办?身陷动漫城输了很多钱