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* 指针,接收任意类型的指针值