这个C代码是如何工作的?
我正在看下面的代码,它是我在C中使用递归以相反顺序打印字符串时遇到的:这个C代码是如何工作的?,c,pointers,recursion,C,Pointers,Recursion,我正在看下面的代码,它是我在C中使用递归以相反顺序打印字符串时遇到的: void ReversePrint(char *str) { //line 1 if(*str) { //line 2 ReversePrint(str+1); //line 3 putchar(*str); //line 4 } } 我对C比较陌生,对第2行感到困惑*str是取消对指针的引用,应该返回当前位置的字符串值。但是如
void ReversePrint(char *str) { //line 1
if(*str) { //line 2
ReversePrint(str+1); //line 3
putchar(*str); //line 4
}
}
我对C比较陌生,对第2行感到困惑<根据我的理解,code>*str是取消对指针的引用,应该返回当前位置的字符串值。但是如何将其用作条件语句的参数(除了布尔右键之外,应该是哪个?)?在第3行中,指针将始终递增到下一个块(因为它是int,所以为4字节)…因此,如果字符串结尾后的下一个内存块中碰巧有数据,那么这段代码不会失败吗
更新:所以c中没有布尔类型,对吗?如果值为0,条件语句的计算结果为“false”,否则为“true”?第2行正在检查当前字符是否为字符串的空终止符-由于C字符串以空终止,并且空字符被视为假值,因此当它到达字符串的结尾时,它将开始展开递归(而不是尝试调用空终止符后面的字符的StrReverse4,这将超出有效数据的界限) 还要注意,指针指向的是
char
,因此指针的增量仅增加1个字节(因为char
是单字节类型)
例如:
0 1 2 3
+--+--+--+--+
|f |o |o |\0|
+--+--+--+--+
str
=0
时,则*str
为'f'
,因此对str+1=1进行递归调用str
=1
时,则*str
为'o'
,因此对str+1=2进行递归调用str
=2
时,则*str
为'o'
,因此对str+1=3进行递归调用str
=3
时,则*str
为'\0'
且\0
为假值,因此如果(*str)
的计算结果为假,则不进行递归调用,从而返回我们得到的递归字符串末尾通常是0字节-如果(*str)行正在检查该字节是否存在,并在到达该字节时停止。C字符串的类型只不过是指向字符的指针。按照惯例,指针指向的是以零字节结尾的字符数组 因此,
*str
是str
指向的字符串的第一个字符
如果
str
指向(空)字符串中的终止空字节,则在条件中使用*str
将计算为false
。字符串末尾有一个0
-因此您有“test”=>[0]'t'[1]'e'[2]'s'[3]'t'[4]0
和if(0)->false
这样就行了
在第3行中,指针将始终递增到下一个块(因为它是int,所以为4字节)
这是错误的,这是char*,它只会增加1。因为char的长度只有1字节
但是如何将其用作条件语句的参数(除了布尔右键之外,应该是哪个?)
您可以在$$处使用if($$)中的任何值,它只会检查其是否为非零,基本上bool也只实现为simple 1=true和0=false
在其他更高级的强类型语言中,你不能在if中使用这些东西,但在C中,一切都归结为数字,你可以使用任何东西
if(1) // evaluates to true
if("string") // evaluates to true
if(0) // evaulates to false
你可以在if中给出任何东西,while条件在C中。条件语句(if
,for
,while
,等等)应使用布尔表达式。如果提供整数值,则计算结果将归结为0==false
或non-0==true
。如前所述,c字符串的终止字符为空字节(整数值0)。因此If
将在字符串末尾(或字符串中的第一个空字节)失败
另一方面,如果对空指针执行*str
,则调用的是未定义的行为;在取消引用之前,应始终验证指针是否有效。1
str
是指向字符的指针。递增str
将使指针指向字符串的第二个字符(因为它是字符数组)。
注意:递增指针将根据指针指向的数据类型递增
例如:
int *p_int;
p_int++; /* Increments by 4 */
double *p_dbl;
p_dbl++; /* Increments by 8 */
二,
对表达式求值,如果结果值为零(
NULL
,\0
,0
),则不执行语句。由于每个字符串都以\0
结尾,因此递归必须在某个时间结束。C没有布尔值的概念:在C中,每个标量类型(即算术和指针类型)都有可用于布尔上下文,其中0
表示false
和非零true
由于字符串以null结尾,终止符将被解释为false
,而其他每个字符(具有非零值!)将被解释为true
。这意味着有一种简单的方法可以迭代字符串的字符:
for(;*str; ++str) { /* so something with *str */ }
StrReverse4()
做同样的事情,但是通过递归而不是迭代。试试这段代码,它与您正在使用的代码一样简单:
int rev(int lower,int upper,char*string)
{
if(lower>upper)
return 0;
else
return rev(lower-1,upper-1,string);
}
这有点离题了,但当我看到这个问题时,我立刻想知道这是否真的比从后面做strlen和迭代要快 所以,我做了一个小测试
#include <string.h>
void reverse1(const char* str)
{
int total = 0;
if (*str) {
reverse1(str+1);
total += *str;
}
}
void reverse2(const char* str)
{
int total = 0;
size_t t = strlen(str);
while (t > 0) {
total += str[--t];
}
}
int main()
{
const char* str = "here I put a very long string ...";
int i=99999;
while (--i > 0) reverseX(str);
}
#包括
void reverse1(常量字符*str)
{
int-total=0;
如果(*str){
反向1(str+1);
总数+=*str;
}
}
void reverse2(常量字符*str)
{
int-total=0;
尺寸t=strlen(str);
而(t>
#include <string.h>
void reverse1(const char* str)
{
int total = 0;
if (*str) {
reverse1(str+1);
total += *str;
}
}
void reverse2(const char* str)
{
int total = 0;
size_t t = strlen(str);
while (t > 0) {
total += str[--t];
}
}
int main()
{
const char* str = "here I put a very long string ...";
int i=99999;
while (--i > 0) reverseX(str);
}