Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
这个C代码是如何工作的?_C_Pointers_Recursion - Fatal编程技术网

这个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是取消对指针的引用,应该返回当前位置的字符串值。但是如

我正在看下面的代码,它是我在C中使用递归以相反顺序打印字符串时遇到的:

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)
    的计算结果为假,则不进行递归调用,从而返回我们得到的递归
  • 最近的递归之后是'putchar('o'),然后是
  • 下一个最新的递归之后是'putchar('o'),然后是
  • 最近的递归后面跟着'putchar('f'),我们就完成了

  • 字符串末尾通常是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);
    }