8_goto和void分析

关键词:goto副作用分析、 void的意义、void*指针的意义

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);
    
STATUS:
    p[0] = n;
    
    free(p);
}


int main()
{
    printf("Begin...\n");
    
    printf("func(10)\n");
    
    func(10);
    
    printf("func(-10)\n");
    
    func(-10);
    
    printf("End...\n");

    return 0;
}

输出结果:

Begin...
func(10)
func(-10)
段错误

总结:goto语句的执行破化了程序的结构化特征

2. void的意义

  • void修饰函数返回值和参数
    如果函数没有返回值,应该将其声明为void
    如果函数没有参数,应该将其声明为void
    void修饰函数返回值和参数是为了表示无
#include <stdio.h>

// 在C语言中,函数定义可以不写任何参数,也可以不写任何的返回值
// 当没有写参数的情况下,编译器认为函数可以接收任意个参数
// 当没有写返回值的情况下,编译器认为返回值为int类型
f() 
{

}

int main()
{
    int i = f(1, 2, 3, 4);
    
    int j = f(2, 4, 5, 6, 6, 7);
    
    return 0;
}

总结:C语言不是强类型语言
需要通过void来声明函数的返回值为空,需要通过void来声明函数的参数个数未0个(注意与C++的区别)。

#include <stdio.h>

void f(void)    
{

}

int main()
{
    f();
    
    return 0;
}

3. 不存在void变量

  • C语言中没有定义void究竟是多大内存的别名,因此不能定义void类型的变量
  • 没有void的标尺,无法在内存中裁剪出void对应的变量
#include <stdio.h>

int main()
{
    void var;       // error
    void array[3];  // error
    
    void* pv;   
    
    return 0;
}

总结:不能定义void类型的变量,可以定义void*类型的指针

小贴士:
ANSI C:标准C语言的规范
扩展C:在ANSI C的基础上进行了扩充(如VS编译器,gcc编译器)

#include <stdio.h>

int main()
{
  printf("%d\n", sizeof(void));   
  
  return 0;
}

上述代码在ANSI C编译器中无法编译通过,但是对于支持GNU标准的gcc编译器而言是合法的。

4. void*指针的意义

  • C语言规定只有相同类型的指针才可以相互赋值
  • void*指针作为左值用于接收任意类型的指针
  • void*指针作为右值使用时需要进行强制类型转换

5. void*作用—指针类型间的转换

#include <stdio.h>
#include <malloc.h>

/*
 *  MemSet(void* src, int length, unsigned char n) : 设置某一段内存中的每个字节为固定字符
 *  在函数传递过程中不需要关心数组类型,因此用void*类型
 */
 
 void MemSet(void* src, int length, unsigned char n)
 {
    unsigned char* p = (unsigned char*)src;
    
    for(int i=0; i<length; i++)
    {
        p[i] = n;
    }
 } 

int main()
{
    int a[5];
    
    MemSet(a, sizeof(a), 0);
    
    for(int i=0; i<5; i++)
    {
        printf("%d\n", a[i]);
    }

    return 0;
}

输出结果:

0
0
0
0
0

6. 小结

  • 现代软件工程中禁用goto语句
  • void是一种抽象的数据类型
  • void类型不能用于定义变量
  • void类型用于声明函数无参数
  • void类型用于声明函数无返回值
  • 可以定义void*类型的指针
  • void*类型的指针可以接收任意类型的指针值
  • void*类型的指针可以作为指针类型转换的中间类型

声明:此文章为本人在学习狄泰软件学院《C语言深度解析》所做的笔记,文章中包含狄泰软件资料内容一切版权归狄泰软件所有!

    原文作者:jacob2359
    原文地址: https://www.jianshu.com/p/f5618c2019ae#comments
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞