关于常量指针的思考

//太无语了 太无语了 偶尔不用live write写东西浏览器就完蛋 都快写完了啊 --

 

//重写了下,刚开始学的菜鸟专用,鸟龄一个多月吧

 

学习vc快两个月了 这段时间一直纠缠于各种常量啊 指针啊 * & 字符什么的 =.= 崩溃

目前还有很多弄不清 但是有一些知道的 先总结一部分吧 关于常量指针的

 

环境:vc控制台应用程序

首先看这里

const char* pcStr;

const char  caStr[]="Hello,Vc";

pcStr="Hello,Ms";

cout<<"pcStr="<<pcStr<<endl<<"caStr="<<caStr;

我们通过上面几行代码可以进行初步测试,为啥一个在声明时初始化(赋初值,或者称为定义?),一个在后面初始化呢?其实都可以在声明时初始化,但是不可以都在后面初始化,因为const关键字说明变量必须在声明时初始化,也就是说后面就不给你机会了,这是const的特点,你可以改成

const char  caStr[9];//注:字符串常量(就是"skkhfsf"这个形式的)后面会自动跟着一个\0,作为一个串的标识,貌似ascII码中终止符排第一个

caStr="Hello,Vc";

这样肯定就报错啦

那么我们就可以看见,pcStr它不是常数!

ok 那它是啥?它叫做指向一个const char的指针

注:记得数组名就是数组的指针,就是数组第一个元素的地址,对吧?

 

好的,继续看,在下面添加代码

pcStr="Hello,Sun";

再次cout,ok,输出正常

再添加caStr="Hello,xx"

再cout,咋样,错了吧?原因如上,const的关键规则

 

既然是vc,在这里就说一下,LPCSTR,LPWSTR,LPTSTR,可以这样记,LP就是指针的意思,这是个指针类型,有W,就说明是wchar_t类型,宽字符集,C代表const,就是说指向常量的指针,STR就是字符串,或者你可以称为以\0标记终止的字符数组.

{

补充一个 一时不懂的话可以略过  但是回头要弄明白

pcStr怎么才回出错 看下面

*pcStr="Hello,eee";

然后cout一下,咋样,错了吧,为啥?呵呵 因为地址存的是常量嘛

}

 

 

ok 再来看

char* const ccpStr="Hello,qqq";

那么这又是个啥玩意儿呢?ok,看官先思考,先cout一下,嗯,正常,

那改为char* const ccpStr;

ccpStr="Hello,qqq";

再cout一下,咦?错了吧,为啥?呵呵 ,因为这个成为一个指向普通字符数组的"常量指针",对的,这个指针本身是个常量,存了哪个地址,那这个地址就不能改变,但是指向的地址不是常量,内容可以改变,这个东西就是说始终指向一个地址,并且要在声明时初始化,我没用过,不过个人感觉蛮危险的呢

ok,在上面的代码继续添加,不改,ccpStr="Hello,www"; 呵呵,这个肯定就错了,说明看上面

 

{

还有一个情况 补充下 这个应该好理解了

*ccpStr="Hello,eee"; 

cout一下,这个就是对的,为啥,因为指向的地方并不是常量嘛 呵呵

}

 

  孙鑫的视频里面有一段专门提到这个问题,感觉很不错,强烈推荐!!  孙鑫有自己的官方网站

貌似是sunxin.org

 

这些都不好记,我发现从右向左比较好读好记,这个大概和老外的语法习惯有关吧--

 

那么这么说来还有个东西 –#    const char* const cccSTR;

汗 这个玩意儿我就不多说了,自己研究吧,不过这个应该没有危险性啦,哈哈,就是不知道有什么用

 

 

此外想到了一个野指针的问题,我这两个月虽然经验不多,但是也遇到了两次.又一次跟我转的那篇<内存>的文章里的情况一样,还有就是关于指向函数中的变量的问题.

比如说

我有个全局变量,char * cpStr;

先写个方法

void Test()

{

char a[]=”Hello,rrr”;

cpStr=a;

cout<<cpStr;

}

 

然后main函数里面,调用这个方法

 

int main()

{

Test();

ok  就到这里 加入后面还有代码 那个cpStr还要使用的话,那就很危险了,你说cpStr现在是什么呢?是哪个字符处?

啥都不是了! 它是个野指针,只是还指向Test方法中的那个临时变量a的地址,但是函数执行完变量所在内存就被回收了,也就是说是个不知道存什么的内存区,但是cpStr还是指向它,很卡怕的野指针,听别人的经验说用完指针后要归位,就是cpStr=NULL;另外还有很多技巧我就不一一说了,我也记不得多少,自己用还是个问题

据说方法展开的栈空间被回收,这些我还没有深入理解.

说到这忽然想到个关于设计的问题,不知道是不是方法需要的数据尽量依靠参数传进来比较好呢?方法的设计要不要考虑耦合性呢?好复杂...>_<

 

不知道指针作为参数时是值引用还是地址引用呢,有知道的告诉俺咯,感觉如果是* pname的操作应该是地址引用,会改变值,如果直接对pname直接赋值呢?是野指针还是值引用? >_<

用局部变量赋值,还是用常量赋值,一样么?

...思考,思考

}

 

 

刚刚测试了下 确实是值引用,但是方法里对*pname(就是那个参数)赋值不行,说是无法从const char[4]转成char  --   我自己倒有点乱了呵呵

同时又想起来 什么时候用char[]  什么时候用char*呢 ><  哎

不过感觉如果是常量串的话本质应该是char[]吧 --

 

我用int类型测了下,在方法里用*pname进行赋值 确实是地址引用,其实想想也没啥奇怪了

 

天 我笨死了 char *pname="xxxx";的话 那pname指向的就是常量 那常量就不能变了啊

那这个就是隐形转换 真正的应该const char*="ffedfsfgf";这样才对

 

用数组的话就不是常量啦,是赋值了,罪过罪过,阿门

 

但是还是感觉字符串的指针处理和各种基本类型指针不一样呢

最起码cout字符串指针的话不会出来地址,而是出来字符串,这是为啥?知道的告诉一下吧

不过稍微有点明白为啥c#中String类型是地址引用类型的了

 

嗯 目前的迷惑中心大概就是char *字符串了吧

posted on 2009-11-18 19:16  Evalon  阅读(274)  评论(2编辑  收藏  举报

导航