2016-10-22 54 views
-1

我写了一个程序来使用指针交换两个字符串。使用指针交换两个字符串打印奇怪的输出

char *names[]={"Sachin","Kapil","Ajay","Sunil","Anil"}; 
cout<<"String II is ";cout<<names[1]; 
cout<<"\nString IV is ";cout<<names[3]; 
char *t; 
t=names[1]; 
names[1]=names[3]; 
names[3]=t; 
cout<<"\nString II is ";cout<<names[1]; 
cout<<"\nString IV is ";cout<<names[3]; 

在第一行中我用炭指针数组以存储串的第一字符的地址。

当我cout的名称[1]和名称[3]:

整个字符串印刷,但不应单独的字符指针的地址被打印?

此外,程序如何打印整个字符串而不是单独打印第一个字符?

编译后,我收到第1行的警告: 警告:不推荐将字符串常量转换为'char *'[-Wwrite-strings] |

该程序按预期运行,但我很想知道它是如何工作的。我遇到了一个实现,他们使用cout.write(names [i],len)打印整个字符串(这很有意义) ,但令我惊讶的是,上述方法也可以工作(即使没有任何增加指针值来打印下一个字符)。

有关上述问题的任何提示和建议,将不胜感激。谢谢!

+0

它必须将'char * names []'分解为两个块。 'char *'和'names []'是一个名为char指针的数组。 –

回答

0

首先 - 为什么你不只是得到地址输出。 当您将任何char*插入流中时,例如std::cout<<s;其中s的类型为char*插入逻辑假定s指向'C'字符串的第一个字符。 'C'字符串是一系列以nul结尾的字符('\0'字符)。 因此,插入逻辑输出该系列字符。

如果您使用std::cout<<static_cast<void*>(c);,则会得到不同的结果,因为插入的void*指针的处理方式不同。

流上的<<运算符被重载,根据你所插入的内容做不同的事情。

现在你为什么得到这个警告。你发现了一些不幸的遗留C++特别是从C继承的行李。 在C早期的旧版本中,如果没有const修饰符,那么就没有办法指出字符串文字(例如“Sachin”)不能修改在运行时以及不同的平台上执行此操作时会产生不同的影响,从修改数据的无害修改,抛出访问异常以修改代码中所有字面引用的字符串值(可能有多个)。

所以当C++出现并引入了const(很快被C采纳)时,很适合在代码const char[]中生成字符串文字的类型。但是,有些编译器(如果您的设置错误!)仍然允许您将文字分配到char[](或char*)以实现向后兼容。 除非你维护古代代码,并且高级程序员已经指示你,否则不要启用该选项。

0

流库识别char *类型并将其视为空终止的c样式字符串,它只是由null终止的字符数组。

要将它打印到打印地址,请将字符串类型转换为void *。

cout << "String II is "; cout << (void *)names[1]; 

现在将输出:

String II is 0x400a0b 

至于为什么不仅印刷在第一字符,这是因为该流库把它当作空结尾的C字符串。但如果你真的只想要第一个字符打印,你可以很容易地做到了这一点:

cout << "String II is "; cout << *names[1]; 

或:

cout << "String II is "; cout << names[1][0]; 

操纵指针像你这样是好的,但操作所包含的内容是不是当宣布就像你有他们一样。所以你应该真的把它们声明为const。这也删除了编译警告。 所以代码会变成。

const char *names[]={"Sachin","Kapil","Ajay","Sunil","Anil"}; 
cout << "\nString II is "; cout << (void*)names[1]; 
cout << "\nString IV is "; cout << (void*)names[3]; 

const char *t; 
t = names[1]; 
names[1] = names[3]; 
names[3] = t; 

cout << "\nString II is "; cout <<(void*)names[1]; 
cout << "\nString IV is "; cout <<(void*)names[3]; 
+1

'endl'事情不正确,'endl'只是强制实际上会损害性能的flush。使用'\ n'很好,实际上是推荐的方法。我会补充说,如果你不想缓冲,比使用'\ n'更好的方法是简单地使用'cerr'而不是'cout'。 –

+0

感谢您澄清@NirFriedman。我不知道这是因为我讨厌iostream库,很少亲自使用它。 – Matt

相关问题