zoukankan      html  css  js  c++  java
  • C 小问题集锦

    摘要:在学习 C 语言编程中遇到的一些容易混淆出错的问题,记录下来备忘。

    C语言学习 小问题集锦

    作者:乌龙哈里
    时间:2015-11-24
    平台:Window7 64bit,C# :Visual Studio Community 2015, C:TCC 0.9.26(x86-64 Win64)

    参考:


    章节:

    • 数组元素 a[n++] 是 a[n] 还是 a[n+1]?
    • 2个递归到底如何运行?
    • 传递数组的元素个数?

    正文:

    一、数组元素 a[n++] 是 a[n] 还是 a[n+1]?

        在学习排序中,看到了一种写法,a[n++],这个a[n++]到底是 a[n]还是 a[n+1]?不用多说,上测试代码:

    #include <stdio.h>
    int main(void){
        int a[4]={1,2,3,4};

        printf("Array: ");
        for(int i=0;i<4;i++){printf("%d ",a[i]);}
        printf(" n=%d ",n);

        int n=0;
        a[n++]=8;

        printf("Array: ");
        for(int i=0;i<4;i++){printf("%d ",a[i]);}
        printf(" n=%d ",n);
        return 0;
    }
    /*结果:
    Array: 1 2 3 4 n=0
    Array: 8 2 3 4 n=1
    */

    结果表明:a[n++] 还是指 a[n],然后n=n+1了。

    二、2个递归如何运行?

    在学习快速排序的时候,遇到了同时有2个递归的情况,如:

    QuickSort(a,left,i-1);
    QuickSort(a,i+1,right);

    他们到底是怎么运行的呢?上测试代码:

    #include <stdio.h>
    int n=0;
    void Recursion(int a,int b){
        if (b>3 ) return;
        if(a!=3) printf("%2d : R: %d %d ",n,a,b);
        n++;
        b++;
        Recursion(0,b);
        Recursion(1,b);
    }
    int main(void){
        Recursion(3,0);
        return 0;
    }
    /*结果:
     1 : R: 0 1
     2 : R: 0 2
     3 : R: 0 3
     4 : R: 1 3
     5 : R: 1 2
     6 : R: 0 3
     7 : R: 1 3
     8 : R: 1 1
     9 : R: 0 2
    10 : R: 0 3
    11 : R: 1 3
    12 : R: 1 2
    13 : R: 0 3
    14 : R: 1 3
    */

        根据递归的原理,用栈记录函数的出入口,我简单地认为把函数压入栈,根据栈后进先出的特性,我把上面的用符号记录过程,把两个函数分别标记为R0,R1。R0-1--代表第1个递归函数,b值为1;R1-2,代表第2个递归函数,b值为2,下来分解:

    步    执行及b值     栈内及b值                描述
      1    R0-1            R1-1                        b=1,执行R0-1,把R1-1压入栈
      2    R0-2            R1-1, R1-2             进入R0,b++为2,执行R0-2,把R1-2压入栈
      3    R0-3            R1-1, R1-2, R1-3    进入R0,b++为3,执行R0-3,把R1-3压入栈
      4    R1-3            R1-1, R1-2             进入R0,b++为4,触发退出,回到栈内取最后一个R1-3执行
      5    R1-2            R1-1                        R1-3执行,触发退出,执行R1-2
      6    R0-3            R1-1, R1-3              进入R1-2,b++为3,执行 R0-3,把R1-3压入栈
      7    R1-3            R1-1                        R0-3触发退出,从栈内取出 R1-3运行
      8    R1-1            R1-2                        运行R1-1,进入R0-2,把R1-2压入栈
      9    R0-2            R1-2, R1-3              运行R0-2,进入R0-3,把R1-3压入栈
    10    R0-3            R1-2, R1-3              运行R0-3,触发退出
    11    R1-3            R1-2                        运行R1-3,触发退出
    12    R1-2            R1-3                        运行R1-2,b++为3,准备进入R0-3,把R1-3压入栈
    13    R0-3            R1-3                        运行R0-3,触发退出
    14    R1-3                                            运行R1-3,触发退出,栈内为空,全部结束。

    脑袋都疼了,那么复杂,这些人到底怎么想出来的,难道他只用知道退出机制及计算过程,根本不关注执行顺序。

    三、传递数组的元素个数?

    在学习排序中,经常要循环,需要知道数组的长度(元素个数),在同个函数内,用
    int len=sizeof(a)/sizeof(a[0]);
    就能知道,把数组传递进函数后,难道也能这样?上测试代码:

    #include <stdio.h>
    void Test(int a[]){
        printf("byref: a %2d, a[0] %d,num %d ",sizeof(a),sizeof(a[0]),sizeof(a)/sizeof(a[0]));
    }
    int main(void){
        int a[]={1,2,3,4};
        printf("none : a %2d, a[0] %d,num %d ",sizeof(a),sizeof(a[0]),sizeof(a)/sizeof(a[0]));
        Test(a);
        return 0;
    }
    /*输出:
    none : a 16, a[0] 4,num 4
    byref: a 8, a[0] 4,num 2
    */

        明显在传递数组的函数内再用这种方式是错误,原因在于数组作为形式参数是指针化了,显示的是指针的大小,64位平台指针是8 byte的。查了一堆资料,除了用结构 struct 把数组包装一下,如下:

    struct A{
        int count;
        int a[];
    };

    这样能通过 count 取得数组大小,但这样又涉及数组的初始化等问题,很是麻烦。


    若还在学习的过程中碰到这些小问题,继续补充。
    未完待续...

  • 相关阅读:
    Java控制台常用命令
    redis如何查看所有的key
    An internal error has occurred. Java heap space
    redis演练
    各种编程实现的树
    MYSQL两个数据库字符集保持一致问题
    进程控制之fork函数
    进程控制之进程标识符
    进程环境之getrlimit和setrlimit函数
    进程环境之setjmp和longjmp函数
  • 原文地址:https://www.cnblogs.com/leemano/p/4990260.html
Copyright © 2011-2022 走看看