2017-02-19 118 views
2

我正在为我正在做的初学C++类做一些编码。在课堂上,我们必须接受另一名学生提交的代码并修复他们创建的错误。代码如下:空终止符 1?

#include <iostream> 
using namespace std; 

int countChars(char *, char); // Function prototype 

int main() 
{ 
    const int SIZE = 51; // Array size 
    char userString[SIZE]; // To hold a string 
    char letter;   // The character to count 

    // Get a string from the user. 
    cout << "Enter a string (up to 50 characters): "; 
    cin.getline(userString, SIZE); 

    // Get a character to count occurrences of within the string. 
    cout << "Enter a character and I will tell you how many\n"; 
    cout << "times it appears in the string: "; 
    cin >> letter; 

    // Display the number of times the character appears. 
    cout << letter << " appears "; 
    cout << countChars(userString, letter) << " times.\n"; 
    return 0; 
} 

int countChars(char *strPtr, char ch) 
{ 
    int times = 0; // Number of times ch appears in the string 

    // Step through the string counting occurrences of ch. 
    while (*strPtr != '\0')// ***** There was a one placed inside the null operator, however, this is not a syntax error, but rather just incorrect. 
    { 
     if (*strPtr == ch) // If the current character equals ch... 
      times++;   // ... increment the counter 
     strPtr++;   // Go to the next char in the string. 
    } 

    return times; 
} 

学生改变了这样的功能,它已空终止为\10,这并没有引起编译也不运行时错误。玩过之后,我发现它也可能是\1并且仍然有效。这怎么可能。我是一个完全noob,所以我很抱歉如果这是一个愚蠢的问题,但我认为这是一个布尔运算符,1是真的,0是错误的。问题是为什么\10\1将作为空终止符。先谢谢你!

+0

'\ number'指转义序列编写由数字代码的象征,就像'\ xnumber'不一样的,但现在你在十六进制指定它。在语法方面,除了只有''\ 0'(在字符串外部也可以表示为'\ x00''或者甚至只是'0')时,这里没有任何错误是一个有效的空终止符。 – Havenard

+0

请注意''\ 1''和其他数字不“仍然有效”。该程序要么有运行时错误,要么有幸运。幸运的是,我的意思是你的'while'循环不断读取数组的末尾,并进入具有不可预知值的内存中。这种语言不会阻止你编写这样的代码,但这就是所谓的“未定义的行为”。什么事情都可能发生。例如,你可能很幸运,并且恰好在下一个位置有一个值为'1'的字节,并且你的程序看起来工作正常。或者没有和你的程序永远循环。或者是其他东西。它没有定义。 – Adam

回答

-1

“\ 0”是唯一被称为NULL终止符的。即使“\ 1”或“10”或甚至“\ 103”工作,只有“\ 0”被称为NULL终止符。我会解释为什么。

在“\ 0”中,0表示ascii表中的OCT值(见下图)。在ascii表中,没有字符的OCT值为0,因此,如果我们尝试使用0,它被称为NULL终止符,因为它指向地面并且没有意义或有用。

现在为什么“\ 10”和“\ 1”有效?因为这些涉及OCT值1和10,它们可以映射到ascii表上的字符,特别是标题的开始Baskspace。类似地,如果您选择指向字母,标点符号或数字的OCT值(例如“\ 102”指向B,则它将输出B.

如果您尝试输入无效数字,如“ \ 8“,那么它只会在屏幕上输出8,因为它不会引用ascii表上的有效字符。

看到这个代码,它总结了所有不同类型的指针:

#include <iostream> 

using namespace std; 

int main(void) 
{ 
    cout << "\0" << endl; // This is NULL; points to the ground 
    cout << "\8"; << endl; // Invalid OCT value; outputs invalid number input with only a warning. No compilation error. Here, 8 will be output 
    cout << "\102"; // Valid; points to B. Any valid OCT value will point to a character, except NULL. 
} 

Ascii Table


编辑:经过一番研究之后,我注意到,正确的使用转义序列确实与只有最少3个数字。因此,在八进制方法之后,即使NULL终止符在技术上也应该写为“\ 000”。但是,如果编译器没有以八进制格式写入,编译器可以明显地告诉哪个八进制值被引用到甚至。换句话说,编译器将“\ 1”解释为“\ 001”。只是一些额外的信息。

我发现这方面的资料:C++ Character Literals

+0

你的第三个例子会输出'f'。因为这是十进制文字,而不是八进制。八进制文字以0开头。说明使用这些值时会发生什么,它的危险是什么,以及为什么循环会停止,即使在字符串内部没有带有该代码的符号也会显着改善答案。 –

+0

不,@Revolver_Ocelot,它确实输出“B”,我现在就自己尝试。事实上,我自己对这件事感到非常惊讶,因为我也认为它遵循十进制。 –

+0

你是对的。在转义序列中,所有数字都被视为八进制数字,除非第一个符号是“x”。 –

3

'\0'表示“具有整数表示0的字符”。类似地,'\10'表示“具有整数表示10的字符”。这就是为什么它不是编译错误 - 只是一个逻辑错误。