zoukankan      html  css  js  c++  java
  • 第8课 goto 和 void 分析

    1. 遭人遗弃的goto

    (1)高手潜规则:禁用goto

    (2)项目经验:程序质量与goto出现的次数成反比

    (3)最后的判决:将goto打入冷宫(1)循环语句的基本工作方式

    【实例分析】goto副作用的分析

    #include <stdio.h>
    #include <malloc.h>
    
    void func(int n)
    {
        int* p = NULL;
    
        if(  n < 0 )
        {
            goto STATUS;
        }
    
        
        p = (int*)malloc(sizeof(int) * n);//n<0时,将不被执行
        
    STATUS:
        p[0] = n;    //n<0时,p内存未申请,出现错误
        
        free(p);
    }
    
    int main()
    {  
        printf("begin...
    ");
        
        printf("func(1)
    ");
        
        func(1);
        
        printf("func(-1)
    ");
        
        func(-1);
        
        printf("end...
    ");
        
        return 0;
    }

    2. void的意义

    (1)void修饰函数返回值和参数——为了表示“无”

      ①如果函数没有返回值,那么应该将其声明为void

      ②如果函数没有参数,应该声明其参数为void

    任意参数 无参(用void声明)
    #include<stdio.h>
    
    f() //f()函数任意参数,返回值默认int型
    {
    
    }
    
    int main()
    {
      int i=f(1,2,3)
    
      return 0;
    }
    #include<stdio.h>
    
    void f(void) //无参无返回值
    {
    
    }
    
    int main()
    {
      int i=f(1,2,3) //error
    
      f();    //ok
    
      return 0;
    }

    (2)不存在void变量

      ①C语言没有定义void究意是多大内存的别名,没有void标尺,无法在内存中裁出大小

    #include<stdio.h>
    void main()
    {
         void var;        //error,不可以是void型的变量
         void array[5];   //error,同上
         void* pv;        //ok,void*的指针是可以的。
    }

      ②小贴士:ANSI C:标准C语言的规范

                        扩展C: 在ANSI C的基础上进行了扩充

    #include<stdio.h>
    
    int main()
    {
      //在ANSI C编译器中无法通,支持GNU标准的gcc下为void大小为1,是合法的
      printf("sizeof(void)=%d
    ",sizeof(void)); 
    }

    (3)void指针的意义

      ①C语言规定只有相同类型的指针才可以相互赋值

      ②void* 指针作为左值用于“接收”任意类型的指针

      ③void* 指针作为右值使用时需要进行强制类型转换

    int* pI = (int*)malloc(sizeof(int));
    char* pC = (char*)malloc(sizeof(char));
    void* p = NULL;
    int* pni = NULL;
    char* pnc = NULL;
    
    p = pI; //ok,void*指针p可接收任何类型的指针
    pni = p; //error,void*须强制类型转换,即pni =(int*)p;
    p = pC;  //ok
    pnc = p; //error,应为pnc=(char*)p;

    【编程实例】通过void*实现MemSet函数

    #include <stdio.h>
    
    void MemSet(void* src, int length, unsigned char n)
    {
        unsigned char* p = (unsigned char*)src;
        
        int i = 0;
        
        for(i=0; i<length; i++)
        {
            p[i] = n;
        }
    }
    
    int main()
    {
        int a[5];//这里可以是任何其他类型,如char a[5];double a[5]等。
        int i = 0;
        
        MemSet(a, sizeof(a), 0);
        
        for(i=0; i<5; i++)
        {
            printf("%d
    ", a[i]);
        }
        
        return 0;
    }

    3. 小结

    (1)现代软件工程中禁用goto语句

    (2)void是一种抽象的数据类型

    (3)void类型不能用于定义变量

    (4)void类型用于声明函数无参数或函数无返回值

    (5)可以定义void*类型的指针,该指针可接受任意类型的指针值

  • 相关阅读:
    CodeForces 347B Fixed Points (水题)
    CodeForces 347A Difference Row (水题)
    CodeForces 346A Alice and Bob (数学最大公约数)
    CodeForces 474C Captain Marmot (数学,旋转,暴力)
    CodeForces 474B Worms (水题,二分)
    CodeForces 474A Keyboard (水题)
    压力测试学习(一)
    算法学习(一)五个常用算法概念了解
    C#语言规范
    异常System.Threading.Thread.AbortInternal
  • 原文地址:https://www.cnblogs.com/5iedu/p/5318617.html
Copyright © 2011-2022 走看看