关于常量指针的思考
//太无语了 太无语了 偶尔不用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 *字符串了吧