遭人唾弃的goto
- 高手潜规则:禁用goto
- 项目经验:程序质量与goto的出现次数成反比;
- 最后的判决:将goto打入冷宫
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(1)\n");
func(1);
printf("func(-1)\n");
func(-1);
printf("end...\n");
return 0;
}
上面例子在n<0的情况下,回去释放未申请的p,导致程序奔溃;
void的意义:void修饰函数返回值和参数
-如果函数没有返回值,那么应该将其申明位void
-如果函数没有参数,应该申明其参数位void
-void修饰函数返回值和参数是为了表示“无”
不存在void变量
-C语言没有定义void究竟是多大内存的别名
-没有void的标尺,无法在内存中裁剪出void对饮的变量
void指针的意义
-C语言规定只有相同类型的指针才能相互赋值;
-void*指针作为左值用于接收任意类型的指针;
- void*指针作为右值使用时需要使用强制类型转换
#include "stdio.h"
int main()
{
int* pI = (int*)malloc(sizeof(int));
char* pC = (char*)malloc(sizeof(char));
void* p = NULL;
int* pni = NULL;
char* pnc = NULL;
p=pI; //OK
pni = p; //oops!
p=pC; //ok
pnc = p; //oops
return 0;
}
示例分析:
#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;
}
输出结果: