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

    遭人遗弃的goto:

    C语言是一种面向过程的结构化语言,其中主要结构有三种,顺序执行、选择执行、循环执行。再复杂的程序也是由这三种结构组合而成的。

    goto破坏了结构化特性,使程序以第四种方式执行,结构化特性被破坏的越严重程序质量越下降。

    现代软件开发中很多企业禁用goto。

    goto破坏结构化特性的示例:

     1 #include <stdio.h>
     2 #include <malloc.h>
     3 
     4 void func(int n)
     5 {
     6     int* p = NULL;
     7 
     8     if(  n < 0 )
     9     {
    10         goto STATUS;
    11     }
    12 
    13     
    14     p = (int*)malloc(sizeof(int) * n);
    15     
    16 STATUS:
    17     p[0] = n;    
    18     
    19     free(p);
    20 }
    21 
    22 int main()
    23 {  
    24     printf("begin...
    ");
    25     
    26     printf("func(1)
    ");
    27     
    28     func(1);
    29     
    30     printf("func(-1)
    ");
    31     
    32     func(-1);
    33     
    34     printf("end...
    ");
    35     
    36     return 0;
    37 }

    程序在第10行直接跳转到第16行,则14行就得不到执行,我们在第17行赋值就会出错。当n大于0才可以正常执行。

    运行结果如下:

    32行的调用会导致程序崩溃。

    void的意义:

    函数如果没有返回值应该定义成void,否则默认为int型。不接受参数的话要定义成void,否则默认接受任意参数。因为C语言并不是一门强类型的语言。不写返回值类型C语言编译器并不认为是错的。

    如果函数不接受任何参数,也没有返回值,那么一定要定义成void。

    不存在void变量:void是一种抽象类型,C语言规范并没有定义void的具体大小,是一种概念上的抽象类型

     虽然不可以定义void类型的变量,但是可以定义void类型的指针。因为指针类型要么四个字节要么八个字节。viod*可以在内存中确定大小。

    小贴士:

    ANSI没有定义void的大小,在gcc编译器中做了扩展,对void定义了大小,可以使用sizeof求void大小。

    上面程序片段的执行结果如下:

     上述代码在bcc编译器中会编译出错。

    在写C语言时要以标准C为准。

    void指针的意义:

    void*是一种更大的类型,可以接受任意指针类型。

    程序示例:

     1 #include <stdio.h>
     2 
     3 void MemSet(void* src, int length, unsigned char n)
     4 {
     5     unsigned char* p = (unsigned char*)src;
     6     
     7     int i = 0;
     8     
     9     for(i=0; i<length; i++)
    10     {
    11         p[i] = n;
    12     }
    13 }
    14 
    15 int main()
    16 {
    17     int a[5];
    18     int i = 0;
    19     
    20     MemSet(a, sizeof(a), 0);
    21     
    22     for(i=0; i<5; i++)
    23     {
    24         printf("%d
    ", a[i]);
    25     }
    26     
    27     return 0;
    28 }

    MemSet的第一个参数是void*,我们要设置一段内存的值,并不关心这段内存是char*还是int*的,因此,第一个参数为void*类型,可以接受任意类型的指针。

    执行结果如下:

    小结:

  • 相关阅读:
    【MongoDB】windows平台搭建Mongo数据库复制集(相似集群)(一)
    关于jave在oracle驱动下事务提交与回滚问题
    将其它图片格式转为.eps格式
    学习OpenBlas
    ZOJ3640-Help Me Escape
    向死而生——我修的死亡学分
    iOS对象属性详解
    http状态码介绍
    8080端口被占用
    图片特效
  • 原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9533295.html
Copyright © 2011-2022 走看看