对于家庭作业,我们必须编写一个简短的程序,使用argc和argv告诉你传递给main的参数的数量,它们的数据地址以及每个参数是什么。我们还必须编写一个名为strlen的函数(我们不允许使用库中包含的任何类似函数),它通过使用指针计算传递给main的每个参数的长度。我的功能总是返回0.抱歉,我问的是这样一个基本问题,但作为一年级学生,我还没有接受过使用调试器的培训。这是我的代码:
int strlen(char * p)
{
char X[50];
p = &X[0];
int i = 0;
while (*(p + i) != '\0')
i++;
return i;
}
我已经尝试了几种不同的东西来解决这个问题,但无论函数总是看起来总是返回值0.是否存在一个我忽略的巨大问题?任何朝着正确方向的推动都会有所帮助,但请不要只给我答案。
答案 0 :(得分:5)
你编写了一个计算本地"字符串"的长度的函数。 X
。数组X
甚至没有初始化。它包含垃圾。您的函数返回该垃圾字符串的长度。它不一定是0
,它只是在你的实验中偶然发生了零。一般情况下,您的函数将返回垃圾值或只是导致程序崩溃。行为未定义。
换句话说,当您将函数调用为strlen("hello")
时,您编写的代码将完全忽略"hello"
字符串。您的函数仍然坚持使用本地数组X
,而不是使用从外部传递的参数字符串"hello"
。
如果你是谁写了这个函数,那真的是一个问题:你为什么这样做?
P.S。 strlen
更合理的实现可能会收到const char *
参数(不是char *
),并在size_t
类型的域中执行计数(不是int
)
P.P.S。 *(p + i)
相当于p[i]
。许多人会发现后者比前者更具可读性。
答案 1 :(得分:1)
首先,你的功能毫无意义;它会覆盖参数,并且数组X未初始化,因此其元素具有一些未指定的值,并且使用此函数的程序具有未定义的行为。 该功能可能如下所示:
size_t strlen( const char * p )
{
size_t i = 0;
while ( *( p + i ) != '\0' ) i++;
return i;
}
或更具可读性
size_t strlen( const char * p )
{
size_t i = 0;
while ( p[i] != '\0' ) i++;
return i;
}
例如
#include <iostream>
size_t strlen( const char * p )
{
size_t i = 0;
while ( p[i] != '\0' ) i++;
return i;
}
int main()
{
char s[] = "Hello gsoble";
std::cout << "The size of the greeting is " << strlen( s ) << std::endl;
}
答案 2 :(得分:0)
摆脱前两行。
int strlen(char * p)
{
int i = 0;
while (*(p + i) != '\0')
i++;
return i;
}
答案 3 :(得分:0)
这是未定义的行为。您正在将X
数组传递给'\0'
,但'\0'
可能永远不会发生,因为X
是具有未定义值的本地对象。您可能会遇到分段错误。
我忽略了一个非常大的问题吗?
您不需要本地阵列。你可以从
开始size_t strlen( const char * p) // take const for safety reasons
{ // and return size_t for compatibility
size_t i = 0;
while ( *(p + i) != '\0') ++i;
return i;
}
答案 4 :(得分:0)
正如其他答案所解释的那样,您将p
设置为等于未初始化的x
,这将为您提供未定义的行为。然而,另一个答案没有给你的是..... 递归(因为为什么不是)
unsigned strlen(const char *p) {
if(*p == '\0') return 0;
return 1 + strlen(p+1);
}
如果你想把它降到1行:
unsigned strlen(const char *p) {
return (*p == '\0') ? 0 : 1 + strlen(p+1);
}