指向char的指针vs指向数组的指针

时间:2015-10-27 19:57:17

标签: c++ pointers char

我认为我对指针有了不错的了解,直到我决定回顾一些所谓的琐碎的例子。

我知道的一件事是,在声明一个数组时说:

int arr[2] {3, 5};

arr将保存数组中第一个元素的值,因此尝试打印(cout << arr)会明确显示arr[0]的地址。即使我认为我的程序使用指针它仍然相似。

我的问题是为什么我可以打印h并输出bonjour,但我不能对p执行相同操作?

看起来当我增加h++并再次打印时,我得到onjour。指针如何与char不同?

#include <iostream>
#include <string>

int main()
{
    char* h = "bonjour";
    int k[4]{3, 4, 5, 6};
    int * p = k;

    std::cout << "Hello, "<< h << "!\n";
}

4 个答案:

答案 0 :(得分:9)

当您流h时,您正在使用this overload

template< class Traits >
basic_ostream<char,Traits>& operator<<( basic_ostream<char,Traits>& os,  
                                        const char* s );

但是当你流p时,你正在使用this one

basic_ostream& operator<<( const void* value );

前者将打印每个字节,直到它到达\0,后者将只打印地址。那就是 - 你正在利用的const char*只是一个特例。

答案 1 :(得分:2)

  

为什么我可以打印#include <iostream> #include <vector> #include <algorithm> #include <iterator> using namespace std; int main() { vector<int> nonprimi; vector<int> primi; for (int i = 0; i < 100; i++) { nonprimi.push_back(i); } for (int i = 0; i < nonprimi.size(); i++) { if (((nonprimi[i] == 2) || (nonprimi[i] == 3) || (nonprimi[i] == 5) || (nonprimi[i] == 7)) || (nonprimi[i] % 2 != 0) && (nonprimi[i] % 3 != 0) && (nonprimi[i] % 5 != 0) && (nonprimi[i] % 7 != 0)) { primi.push_back(i); } } for (int i = 0; i < primi.size(); i++) { cout << primi[i] << " "; } // or in a more STL way // copy(primi.begin(), primi.end(), ostream_iterator<int>(cout, " ")); // system("pause"); return 0; } 并将h作为输出,我不能对bonjour执行相同操作?看起来当我增加p并再次打印时,我得到h++。指针如何与onjour不同?

标准库提供了char函数的两个重载来处理指针。

成员函数重载:

operator<<

和非成员函数重载:

basic_ostream& operator<<( const void* value );

template< class Traits > basic_ostream<char,Traits>& operator<<( basic_ostream<char,Traits>& os, const char* s ); 用于所有非cout << ptrchar*类型的指针时,会调用第一个。第二个用于tpe char const*char*的所有指针。第二个输出一直到终止空字符,而第一个输出指针值。

这解释了输出。

理解为什么标准库以不同方式对待它们具有指导意义。

语言和标准库对由char const*char*表示的空终止字符串进行例外处理。处理字符串时,空字符(char const*)充当标记字符串结尾的标记值。其他类型没有这样的价值。因此,'\0'无法对int*进行处理。

答案 2 :(得分:1)

在某些情况下,

char*可能很特殊,因为C决定用它来表示字符串。在这种情况下,char*引用空终止的字符数组,即C-string。您可以打印h但不打p的原因是因为存在一个对char*执行特殊处理的函数:

 std::ostream::operator<<(std::ostream& os, const char*);

您可以提供自己的重载来打印空终止的整数数组:

std::ostream& operator<<(std::ostream& os, const int* arr) {
   while (int i = *arr++) {
      os << i;
      if (*arr) os << ", ";
   }
   return os;
}

int main()
{
  const int arr[] = {1, 2 ,3, 4, 0};
  std::cout << arr << "\n";
}

然而,这是非常危险的,因为大多数整数数组不是以零结尾,而且并非所有指向整数的指针都是数组。

答案 3 :(得分:0)

我认为这与operator <<char*的{​​{1}}有关。 C程序员用于将终止的字符串打印出来,因此创建了一个方法来打印它们。 int*可以直接打印。 int将无法打印出整个字符串。