遭人遗弃的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...\n");
25     
26     printf("func(1)\n");
27     
28     func(1);
29     
30     printf("func(-1)\n");
31     
32     func(-1);
33     
34     printf("end...\n");
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\n", a[i]);
25     }
26     
27     return 0;
28 }

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

执行结果如下:

 

小结:

 

posted on 2018-08-25 11:20  周伯通789  阅读(226)  评论(0编辑  收藏  举报