📜  字符指针的异常行为

📅  最后修改于: 2021-05-30 04:54:01             🧑  作者: Mango

在C++中,cout使用字符指针/数组显示不同的打印行为,这与其他数据类型的指针/数组不同。因此,本文将首先解释cout在字符指针上的行为方式,然后讨论其原因和工作机理。

范例1:

C++
// C++ program to illustrate difference
// between behaviour of integer pointer
// and character pointer
#include 
using namespace std;
  
// Driver Code
int main()
{
    // Integer array
    int a[] = { 1, 2, 3 };
  
    // Character array
    char ch[] = "abc";
  
    // Print the value of a and b
    cout << a << endl;
  
    cout << ch << endl;
    return 0;
}


C++
// C++ program to illustrate behaviour
// of character pointer pointing to
// character array
#include 
using namespace std;
  
// Driver Code
int main()
{
    // Character array b
    char b[] = "abc";
  
    // Pointer to character array
    char* c = &b[0];
  
    // Print the value of c
    cout << c << endl;
}


C++
// C++ program to illustrate difference
// between behaviour of character and
// character pointer
#include 
using namespace std;
  
// Drive Code
int main()
{
    char c = '$';
    char* p = &c;
  
    cout << c << endl;
    cout << p << endl;
}


C++
// C++ program to illustrate
// printing of character array
#include 
using namespace std;
  
// Driver Code
int main()
{
    // Character array
    char c[] = "abc";
  
    // print value of c, c[0] and *c
    cout << c << endl;
    cout << c[0] << endl;
    cout << *c << endl;
}


C++
// C++ program to illustrate behaviour
// of typecasted character pointer
#include 
using namespace std;
  
// Driver Code
int main()
{
    char c[] = { "abc" };
    char* b = c;
    cout << (void*)b;
}


C++
// C++ program to illustrate the
// utilization of unusual behaviour
// of character pointer
#include 
using namespace std;
  
// Function that prints the pattern
void printPattern(char* ch)
{
    // Base Condition
    if (*ch == '\0')
        return;
  
    // Recursion function call after
    // excluding the current character
    printPattern(ch + 1);
  
    // Print the whole string starting
    // from base address stored in 'ch'
    cout << ch << endl;
}
  
// Driver Code
int main()
{
    char ch[] = { "abcd" };
  
    // Function Call
    printPattern(ch);
  
    return 0;
}


输出:
0x7ffc623e56c0
abc

解释:
从上面的代码中,很明显:

  • 使用指向数组的整数指针时, cout打印该整数数组的基地址。
  • 但是,当使用字符指针时, cout会打印完整的字符数组(直到遇到空字符为止),而不是打印字符数组的基址。

范例2:

C++

// C++ program to illustrate behaviour
// of character pointer pointing to
// character array
#include 
using namespace std;
  
// Driver Code
int main()
{
    // Character array b
    char b[] = "abc";
  
    // Pointer to character array
    char* c = &b[0];
  
    // Print the value of c
    cout << c << endl;
}
输出:
abc

解释:
同样在此示例中,字符类型指针c正在存储char数组b []的基地址,因此,当与cout一起使用时,它将开始打印该基地址中的每个字符,直到遇到NULL字符为止。

范例3:

C++

// C++ program to illustrate difference
// between behaviour of character and
// character pointer
#include 
using namespace std;
  
// Drive Code
int main()
{
    char c = '$';
    char* p = &c;
  
    cout << c << endl;
    cout << p << endl;
}
输出:
abc
a
a

输出:

解释:
在上面的示例中, c是一个简单的字符变量,它按预期方式打印存储在其中的值。当与cout一起使用时, p是字符指针,导致每个字符的打印,直到遇到空字符为止。因此,在‘$’之后输出了一些垃圾值。这仅表示在内存中将空字符放在了‘a’字符(因为在这种情况下,与字符数组不同,在有用数据完成后不会自动存储空字符),因此它将停止打印并给出获得的输出。

字符指针异常行为背后的原因

其原因在于“运算符重载”的概念对于不同类型的输入,'<<‘运算符会过载。在const void *重载的情况下,它仅输出地址。但是对于const char *重载,它将开始打印每个字符,直到遇到空字符为止(将输入作为C — style 字符串)。

范例4:

C++

// C++ program to illustrate
// printing of character array
#include 
using namespace std;
  
// Driver Code
int main()
{
    // Character array
    char c[] = "abc";
  
    // print value of c, c[0] and *c
    cout << c << endl;
    cout << c[0] << endl;
    cout << *c << endl;
}
输出:
abc
a
a

说明:在上面的示例中:

  • 只有带有cout的’c’被视为const char *,并且<<对该输入的运算符重载被调用,因此每个字符被打印到空字符为止。
  • 当使用c [0],即*(c + 0)时,它仅取消引用特定的存储位置并仅打印存储在该位置的值。
  • 类似地,对于* c与*(c + 0)相同。

注意:如果将输出类型转换为不会被视为C样式字符串,则可以纠正异常行为。
范例5:

C++

// C++ program to illustrate behaviour
// of typecasted character pointer
#include 
using namespace std;
  
// Driver Code
int main()
{
    char c[] = { "abc" };
    char* b = c;
    cout << (void*)b;
}
输出:
0x7ffe66f7f420

解释:
在上面的示例中,在输出中获得了字符数组的基地址。

通过字符指针利用异常行为

给定一个字符串,按照以下示例所示打印模式:

C++

// C++ program to illustrate the
// utilization of unusual behaviour
// of character pointer
#include 
using namespace std;
  
// Function that prints the pattern
void printPattern(char* ch)
{
    // Base Condition
    if (*ch == '\0')
        return;
  
    // Recursion function call after
    // excluding the current character
    printPattern(ch + 1);
  
    // Print the whole string starting
    // from base address stored in 'ch'
    cout << ch << endl;
}
  
// Driver Code
int main()
{
    char ch[] = { "abcd" };
  
    // Function Call
    printPattern(ch);
  
    return 0;
}
输出:
d
cd
bcd
abcd
要从最佳影片策划和实践问题去学习,检查了C++基础课程为基础,以先进的C++和C++ STL课程基础加上STL。要完成从学习语言到DS Algo等的更多准备工作,请参阅“完整面试准备课程”