第8课 - goto和void分析

第8课 - goto和void分析

1. 遭人嫌弃的goto

(1)高手潜规则:禁用goto

(2)项目经验:程序质量与goto的出现次数成反比;c语言是一门结构化语言,goto会破坏C语言的结构化特性。

(3)最后的判决:将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     p = (int*)malloc(sizeof(int) * n);  // 当 n<0 时不执行这行
14     
15 STATUS:
16     p[0] = n;    // n<0 时,p为野指针,会产生段错误
17     
18     free(p);
19 }
20 
21 int main()
22 {  
23     printf("begin...\n");
24 
25     printf("func(1)\n");
26     func(1);
27     
28     printf("func(-1)\n");
29     func(-1);
30     
31     printf("end...\n");
32     
33     return 0;
34 }

2. void的意义

2.1 void修饰函数返回值和参数

(1)void 修饰函数返回值和参数是为了表示 "无"

(2)如果函数没有返回值,那么应该将其声明为void;否则编译器默认返回值类型为int

(3)如果函数没有参数,应该声明其参数为void;否则编译器默认函数可以传递任意多个参数

 1 #include <stdio.h>
 2 
 3 /*
 4 // 若函数没有返回值,编译器默认返回值为int类型
 5 // 若函数没有参数,编译器默认函数可以传递任意个参数 
 6 f()    
 7 {
 8 
 9 }
10 */
11 
12 void f(void)   // 函数没有返回值,不接受参数
13 {
14 
15 }
16 
17 int main()
18 {
19     // int i = f(1, 2, 3);
20 
21     return 0;
22 }

2.2 不存在void变量

C语言没有定义void究竟是多大内存的别名,因此没有void的标尺,无法在内存中裁剪出void对应的变量(void只是一种抽象的类型)。

 1 #include <stdio.h>
 2 
 3 int main()
 4 {
 5     // void var;    // error
 6     // void array[5];   // error
 7 
 8     void *pv;   // 指针要么为4字节,要么为8字节,可以定义void类型的指针变量
 9 
10     return 0;
11 }

小贴士:

ANSI C:标准C语言的规范

扩展C:编译器厂商在ANSI C的基础上进行了扩充,像我们平时使用的gcc、VS编译器就是使用的扩展C

【void在ANSI C和扩展C中的区别】

1 #include <stdio.h>
2 
3 int main()
4 {
5     printf("cc sizeof(void) = %zu\n", sizeof(void));    // 在ANSI C编译器中编译无法通过
6                                                         // 在支持GNU标准的gcc编译器中编译通过,结果为1
7 
8     return 0;
9 }

bcc32编译器(使用ANSI C标准)  ==>   编译失败

  

gcc编译器  ==>  编译通过

  

2.3 void指针的意义

(1)C语言规定只有相同类型的指针才可以相互赋值

(2)void *指针作为左值用于接收任意类型的指针

(3)void *指针作为右值使用时需要进行强制类型转换

     

【通过void*实现MemSet函数】

 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]; // char a[5] double 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 }

 

posted @ 2019-11-13 22:46  Hengs  阅读(290)  评论(0编辑  收藏  举报