• 第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*类型的指针,该指针可接受任意类型的指针值

  • 相关阅读:
    SharePoint 2010 新体验6 开发人员面板
    用JavaScript实现一个Timeline
    SharePoint 2010新体验2 – Ribbon界面
    SharePoint 2010 新体验5 Office Web Applications
    SharePoint 2010新体验1
    ES6 学习(1)
    ES6 学习(4) 字符串的扩展
    ES6学习(2)
    ES6 学习(5) 正则的扩展
    那些最近工作中遇到的插件
  • 原文地址:https://www.cnblogs.com/5iedu/p/5318617.html
Copyright © 2020-2023  润新知