C++字符字符串数组指针的指针:

C/C++中字符指针数组及指向指针的指针的含义
出处:PConline&
作者:管宁
责任编辑:huangpeidan&
  就指向指针的指针,很早以前在说指针的时候说过,但后来发现很多人还是比较难以理解,这一次我们再次仔细说一说指向指针的指针。  先看下面的代码,注意看代码中的注解:#include&&iostream&& #include&&string&& using&namespace&& & void&print_char(char*&array[],int&len);//函数原形声明& & void&main(void)&&& {& //-----------------------------段1-----------------------------------------& &&&&char&*a[]={"abc","cde","fgh"};//字符指针数组& &&&&char*&*b=a;//定义一个指向指针的指针,并赋予指针数组首地址所指向的第一个字符串的地址也就是abc\0字符串的首地址& &&&&cout&&*b&&"|"&&*(b+1)&&"|"&&*(b+2)&&& //-------------------------------------------------------------------------& & //-----------------------------段2-----------------------------------------& &&&&char*&test[]={"abc","cde","fgh"};//注意这里是引号,表示是字符串,以后的地址每加1就是加4位(在32位系统上)& &&&&int&num=sizeof(test)/sizeof(char*);//计算字符串个数& &&&&print_char(test,num);& &&&&cin.get();& //-------------------------------------------------------------------------& }& & void&print_char(char*&array[],int&len)//当调用的时候传递进来的不是数组,而是字符指针他每加1也就是加上sizeof(char*)的长度& {& &&&&for(int&i=0;i&i++)& &&&&{& &&&&&&&&cout&&*array++&&& &&&&}& }  下面我们来仔细说明一下字符指针数组和指向指针的指针,段1中的程序是下面的样子:char&*a[]={"abc","cde","fgh"};& char*&*b=a;& cout&&*b&&"|"&&*(b+1)&&"|"&&*(b+2)&&  char *a[]定义了一个指针数组,注意不是char[], char[]是不能同时初始化为三个字符的,定义以后的a[]其实内部有三个内存位置,分别存储了abc\0,cde\0,fgh\0,三个字符串的起始地址,而这三个位置的内存地址却不是这三个字符串的起始地址,在这个例子中a[]是存储在栈空间内的,而三个字符串却是存储在静态内存空间内的const区域中的,接下去我们看到了char* *b=a;这里是定义了一个指向指针的指针,如果你写成char *b=a;那么是错误的,因为编译器会返回一个无法将char* *[3]转换给char *的错误,b=a的赋值,实际上是把a的首地址赋给了b,由于b是一个指向指针的指针,程序的输出cout&&*b&&"|"&&*(b+1)&&"|"&&*(b+2)&&   结果是abc cde fgh   可以看出每一次内存地址的+1操作事实上是一次加sizeof(char*)的操作,我们在32位的系统中sizeof(char*)的长度是4,所以每加1也就是+4,实际上是*a[]内部三个位置的+1,所以*(b+1)的结果自然就是cde了,我们这时候可能会问,为什么输出是cde而不是c一个呢?答案是这样的,在c++中,输出字符指针就是输出字符串,程序会自动在遇到\0后停止.   我们最后分析一下段2中的代码,段2中我们调用了print_array()这个函数,这个函数中形式参数是char *array[]和代码中的char *test[]一样,同为字符指针,当你把参数传递过来的时候,事实上不是把数组内容传递过来,test的首地址传递了进来,由于array是指针,所以在内存中它在栈区,具有变量一样的性质,可以为左值,所以我们输出写成了,cout&&*array++&&当然我们也可以改写为cout&&array[i]&&endl,这里在循环中的每次加1操作和段1代码总的道理是一样的,注意看下面的图!   到这里这两个非常重要的知识点我们都说完了,说归说,要想透彻理解希望读者多动手,多观察,熟能生巧。  下面是内存结构示意图:
相关软件:&&/&&&&/&&&&/&&&&/&&
函数的参数不仅可以是整型、浮点型、字符型等数据,还可以是指针类型。它的作用是将一个变量的地址传送给被调用函数的形参。
【例6.3】题目同例6.2,即对输入的两个整数按大小顺序输出。这里用函数处理,而且用指针类型的数据作函数参数。程序如下:
&iostream&
int main( )
void swap(int *p1,int *p2); //函数声明
int *pointer_1,*pointer_2,a,b; //定义指针变量pointer_1,pointer_2,整型变量a,b
cin&&a&&b;
pointer_1=&a; //使pointer_1指向a
pointer_2=&b; //使pointer_2指向b
if(a&b) swap(pointer_1,pointer_2); //如果a&b,使*pointer_1和*pointer_2互换
cout&&&max=&&&a&&& min=&&&b&& //a已是大数,b是小数
void swap(int *p1,int *p2) //函数的作用是将*p1的值与*p2的值交换
运行情况如下:
max=78 min=45
请注意:不要将main函数中的swap函数调用写成
& &if(a&b) swap(*pointer_1,&*pointer_2);
请注意交换*p1和*p2的值是如何实现的。如果写成以下这样就有问题了:
void swap(int *p1, int *p2)
*temp=*p1;
//此语句有问题
本例采取的方法是交换a和b的值,而p1和p2的值不变。这恰和例6.2相反。
可以看到,在执行swap函数后,主函数中的变量a和b的值改变了。这个改变不是通过将形参值传回实参来实现的。请读者考虑一下能否通过调用下面的函数实现a和b互换。
void swap(int x, int y)
在main函数中用&swap(a,&b);&调用swap函数,会有什么结果呢?在函数调用时,a的值传送给x,b的值传送给y,如图6.10(a)所示。执行完swap函数最后一个语句后,x和y的值是互换了,但main函数中的a和b并未互换,如图6.10(b)所示。也就是说由于虚实结合是采取单向的&值传递&方式,只能从实参向形参传数据,形参值的改变无法回传给实参。
为了使在函数中改变了的变量值能被main函数所用,不能采取把要改变值的变量作为参数的办法,而应该用指针变量作为函数参数。在函数执行过程中使指针变量所指向的变量值发生变化,函数调用结束后,这些变量值的变化依然保留下来,这样就实现了&通过调用函数使变量的值发生变化,在主调函数中使用这些改变了的值&的目的。
如果想通过函数调用得到n个要改变的值,可以采取下面的步骤:
在主调函数中设n个变量,用n个指针变量指向它们;
编写被调用函数,其形参为n个指针变量,这些形参指针变量应当与主调函数中的n个指针变量具有相同的基类型;
在主调函数中将n个指针变量作实参,将它们的值(是地址值)传给所调用函数的n个形参指针变量,这样,形参指针变量也指向这n个变量;
通过形参指针变量的指向,改变该n个变量的值;
在主调函数中就可以使用这些改变了值的变量。
请注意,不能企图通过改变形参指针变量的值而使实参指针变量的值改变。请分析下面程序:
&iostream&
int main( )
void swap(int *p1,int *p2);
int *pointer_1,*pointer_2,a,b;
cin&&a&&b;
pointer_1=&a;
pointer_2=&b;
if(a&b) swap(pointer_1,pointer_2);
cout&&&max=&&&a&&& min=&&&b&&
void swap(int *p1,int *p2)
实参变量和形参变量之间的数据传递是单向的&值传递&方式。指针变量作函数参数也要遵循这一规则。调用函数时不会改变实参指针变量的值,但可以改变实参指针变量所指向变量的值。
函数的调用可以(而且只可以)得到一个返回值(即函数值),而使用指针变量作函数参数,就可以通过指针变量改变主调函数中变量的值,相当于通过函数调用从被调用的函数中得到多个值。如果不用指针变量是难以做到这一点的。
【例6.4】输入a,b,c 3个整数,按由大到小的顺序输出。
用上面介绍的方法,用3个指针变量指向3个整型变量,然后用swap函数来实现互换3个整型变量的值。程序如下:
#include &iostream&
int main( )
void exchange(int *,int *,int *);
//对exchange函数的声明
int a,b,c,*p1,*p2,*p3;
cin&&a&&b&&c;
//输入3个整数
p1=&a;p2=&b;p3=&c;
//指向3个整型变量
exchange(p1,p2,p3);
//交换p1,p2,p3指向的3个整型变量的值
cout&&a&&& &&&b&&& &&&c&&
//按由大到小的顺序输出3个整数
void exchange(int *q1,int *q2,int *q3)
void swap(int *,int *);
//对swap函数的声明
if(*q1&*q2) swap(q1,q2);
//调用swap,将q1与q2所指向的变量的值互换
if(*q1&*q3) swap(q1,q3);
//调用swap,将q1与q3所指向的变量的值互换
if(*q2&*q3) swap(q2,q3);
//调用swap,将q2与q3所指向的变量的值互换
void swap(int *pt1,int *pt2)
//将pt1与pt2所指向的变量的值互换
temp=*pt1;
*pt1=*pt2;
运行情况如下:
12 -56 87↙问一个delete字符指针的问题(大神请进)_c++吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:280,823贴子:
问一个delete字符指针的问题(大神请进)收藏
源代码如下:
c++海同强大的师资阵容,因人制定课程内容,分阶段学习.c++就到正规IT技术培训机构-海同科技,培训IT技术面对面教学,免费重读!
# include &iostream&int main (void){
char* p = new char[21];
p = "Hello World";
cout && p &&
return 0;}
delete 指针P的时候会出错
lz,这不是指针数组啊,好像直接delete p就行了
这个问题应该去C吧…大家都不用char *了吧
std::string果然省事多了……
请楼主new[] 对应delete[]
new对应delete
,其实在这里撤销的意义不大,因为程序马上就结束了,到时候系统把所以内存照单全受
这里有个问题p=&Hello World&;
没报错? 这是string的赋值方法吧
这道题的问题在于这里:char*是指向char的指针 而char a[21] 是数组 应用*p=&hello world&; 懂? 还是delete []
这是错误信息
c++培训课程,美国上市公司&达内&出品c++课程,15年教学经验,总监级c++讲师亲授!!达内开创&先就业后付款&模式.名企项目总监授课,成就&稀缺级&c/c++软件工程师
好像可以这么写char*p=new char[21](&hello world&);
…我是说把(&00000&)改成=”00000” 获取的时候用字符串初始化
char[] p=new char[21];才能用带括号的删除方法...
总之楼主的代码声明的是个指向新地址的字符指针
果然用我“发明”的代码会报错...话说我是用iOS 7在测试代码...
前面各位说了这么多就没说到点的
c4droid无压力,怎么都不会报错……
这样 strcpy(p, &Hello World&);
跟方括号没关系,你的p指向只读的内存页也就是常量字符串,delete常量能不出事?
随机数种子是时间,时间是一直变化的,srand是线性同余算法的伪随机数,只有提供了不同的种子才会是真正的随机数。--Quietly Brilliant 谦和之中见卓越
好多不懂装懂的家伙在误导楼主
把p赋值为常量字符串并不是复制字符串内容,而是赋值为常量的地址!因为字符串常量被解释为指向字符串的地址。所以,你的delete语句是在尝试删除字符串常量,所以出现错误。而你申请的内存却没有进行delete操作。除了char数组的赋值初始化,其他时候c风格字符串是不能直接赋值的。你需要使用strcpy函数。
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或2015年8月 Delphi大版内专家分月排行榜第二2015年7月 Delphi大版内专家分月排行榜第二2014年8月 C++ Builder大版内专家分月排行榜第二2013年9月 C++ Builder大版内专家分月排行榜第二2013年6月 C++ Builder大版内专家分月排行榜第二2013年5月 C++ Builder大版内专家分月排行榜第二2013年4月 C++ Builder大版内专家分月排行榜第二2013年3月 C++ Builder大版内专家分月排行榜第二2012年9月 C++ Builder大版内专家分月排行榜第二2012年8月 C++ Builder大版内专家分月排行榜第二2012年3月 C++ Builder大版内专家分月排行榜第二2012年2月 C++ Builder大版内专家分月排行榜第二2011年7月 C++ Builder大版内专家分月排行榜第二
2014年7月 C++ Builder大版内专家分月排行榜第三2014年6月 C++ Builder大版内专家分月排行榜第三2013年8月 C++ Builder大版内专家分月排行榜第三2013年7月 C++ Builder大版内专家分月排行榜第三2013年1月 C++ Builder大版内专家分月排行榜第三2012年12月 C++ Builder大版内专家分月排行榜第三2012年11月 C++ Builder大版内专家分月排行榜第三2011年11月 C++ Builder大版内专家分月排行榜第三2011年8月 C++ Builder大版内专家分月排行榜第三2011年6月 C++ Builder大版内专家分月排行榜第三
2016年2月 C/C++大版内专家分月排行榜第三2016年1月 C/C++大版内专家分月排行榜第三
2016年2月 C/C++大版内专家分月排行榜第三2016年1月 C/C++大版内专家分月排行榜第三
2016年2月 C/C++大版内专家分月排行榜第三2016年1月 C/C++大版内专家分月排行榜第三
本帖子已过去太久远了,不再提供回复功能。

我要回帖

更多关于 字符串数组指针的指针 的文章

 

随机推荐