【C】8. goto 和 void 分析

 

goto 分析

现代软件工程中禁止用goto语句

goto副作用程序分析

#include <stdio.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(1)\n");
    
    func(1);
    
    printf("func(-1)\n");
    
    func(-1);
    
    printf("end...\n");
    
    return 0;
}

输出:

begin...
func(1)
func(-1)
Segmentation fault (core dumped)

goto 破坏了程序的执行流,导致释放 NULL 指针

Void分析

  • 如果函数没有返回值,那么应该将其声明为void
  • 如果函数没有返回值,应该声明其参数为void
  •  void 修饰函数返回值和参数是为了表示“无”
f()
{
    
}

int i = f(1, 2, 3);
// 没写参数的话,编译器会认为会接收任意的多参数
// 返回的是int参数(C语言不是强类型的语言)

用于申明函数无参数;用于声明函数无返回值如下

void f(void)

不存在 void 变量

  • 它是一种抽象的数据类型,所以不存在用它去定义变量
  • 标准的c语言没有定义void是多大内存的别名,只是概念上的类型

扩展C是编译厂商自行扩展的

printf("%d\n", sizeof(void));

在 ANSI C 编译器中无法编译,在 GCC 编译器下为内存的小为1,bcc编译器下就不行了。

void 指针的意义

  • C语言规定只有相同的类型的指针才可以相互赋值
  • 可以定义void*的指针(因为任意的指针都是固定的别名,肯定能在内存中分配 空间)
  • void* 指针作为左值用于接收任意类型的的指针,
  • void*作为右值是使用时需要强制类型转化(C99标准中不需要强制转换)
int * PI = (int *)malloc(sizeof(int));
char* pC = (char*)malloc(sizeof(char));
void* p = NULL;
int* pni = NULL;
char* pnc = NULL;

p = PI;
pni = (int*)p;
p = pC;
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];
    int i = 0;
    
    MemSet(a, sizeof(a), 0);
    
    for(i=0; i<5; i++)
    {
        printf("%d\n", a[i]);
    }
    
    return 0;
}
0
0
0
0
0

void* src 这样表示可以接收任意类型的指针

小结

  • 现代软件禁用goto语句
  • void 是抽象的数据类型,不能定义变量
  • void 类型用于声明函数无参数,函数吴返回值
  • 可以定义 void* 指针,接收任意类型的指针值
发布了84 篇原创文章 · 获赞 0 · 访问量 741

猜你喜欢

转载自blog.csdn.net/zhabin0607/article/details/103536181