我正在刷一些C ++,所以我试图解决的一个问题是从字符指针中计算字符,并根据我期望的内容进行检查。但是在我的解决方案中,我注意到了一个奇特的结果。我将一个char的引用传递给了我的函数,它返回了一个3.为什么引用测试会返回一个3的数字来引用一个字符?
我意识到该字符没有空终止符,因此代码会继续计数但最终会返回结果,因此这意味着解决方案不足。有什么想法让它更健壮吗?这是我的解决方案和结果。
CountCharacters.cpp
#include <cstdio>
#include <iostream>
#define ASSERT_EQUALS(paramx1, paramx2) \
{\
int param1 = paramx1;\
int param2 = paramx2;\
if (param1==param2)\
std::cout << "PASS! param1=" << param1 << " param2=" << param2 << std::endl;\
else\
std::cout << "FAIL! param1=" << param1 << " param2=" << param2 << std::endl;\
}
int countCharacters(const char * characters);
int main()
{
char character = '1';
ASSERT_EQUALS(countCharacters("string8\0"), 7);
ASSERT_EQUALS(countCharacters("\0"), 0);
ASSERT_EQUALS(countCharacters(""), 0);
ASSERT_EQUALS(countCharacters(NULL), 0);
ASSERT_EQUALS(countCharacters(&character), 1);
ASSERT_EQUALS(countCharacters('\0'), 0);
return 0;
}
int countCharacters(const char * characters)
{
if (!characters) return 0;
int count = 0;
const char * mySpot = characters;
while (*(mySpot) != '\0')
{
std::cout << "Count=" << count << " mySpot=" << *(mySpot) << std::endl;
count++;
mySpot++;
}
return count;
}
结果:
PASS! param1=7 param2=7
PASS! param1=0 param2=0
PASS! param1=0 param2=0
PASS! param1=0 param2=0
FAIL! param1=2 param2=1
PASS! param1=0 param2=0
答案 0 :(得分:1)
您没有传递对角色的引用。你正在传递一个指针。具体来说,这是一个指针:
&character
&amp;学习c ++时,*符号有点混乱。根据它们所在的位置,它们可以是指针或参考:
char character = '1'; // <- char variable
char* characterPtr = &character; // <- pointer to the char variable
char& characterRef = *characterPtr; // <- reference to the char variable
因此,您将指针传递给一个字符,并且您的函数将其视为字符串的头部并计算字符直到它达到nullptr。恰好有几个字符,这就是你获得价值2的原因。
编辑:C / C ++没有本机字符串类型,只有字符类型。因此,您需要像您所包含的库来处理像字符串一样的字符。惯例是nullptr终止字符串。所以,你很好地运用了这个约定,但也证明了一个问题,即指向一个字符的指针和指向一个字符串头部的字符的指针之间没有区别,因此很容易意外地通过指向函数的字符指针,指向期望字符串的函数。如果函数开始将字符复制到字符串中,事情会变得非常有趣。因为它假设你分配了那个内存,但它可能是其他数据然后被压扁。
除了危险之外,使用字符串的另一个主要缺点是操纵它们非常繁琐,因为它们没有本机功能。因此,编写像STL这样的好库来解决这些问题。它们不需要指针,因此使用起来更安全(你可以使用引用代替并进行边界检查),并且它们有很多内置方法,因此减少了你需要做的编码量