禁用goto:
#include<stdio.h>
#include<malloc.h>
void f1(int n)
{
int* p=NULL;
if(n<0)
{
goto STATUS;
}
p = (int*)malloc(sizeof(int)*n); //goto之后,改行代码不会被执行
STATUS:
p[0] = n;
free (p);
}
int main()
{
printf("Begin!\n");
printf("f1(1)\n");
f1(1);
printf("f1(-1)\n");
f1(-1); //段错误
printf("end!\n");
return 0;
}
在linux下使用Gcc编译运行代码,执行情况如下:
delphi@delphi-vm:~/will$ ./a.out
Begin!
f1(1)
f1(-1)
段错误
goto语言破坏了程序的顺序执行结构。
void的意义:
如果函数没有返回值,那么将函数声明为void;
如果函数没有参数,那么将其参数声明为void。(不能为空)
void修饰函数返回值和参数的目的在于表示“无”。
观察下面代码,体会void的作用:
f1() //可以接受任意多的参数,返回值默认为int
{
}
void f2 (void) //不接受参数,无返回值
{
}
int main()
{
int i=f1(1, 2, 3);
return 0;
}
需要注意的是:
不存在void变量——C语言并没有对void究竟占多大内存进行定义;
观察下面代码:
#include<stdio.h>
int main()
{
void i; //error
void array[]; //error
void *p; //right void可以用来声明指针。
return 0;
}
可以发现,无法用void来声明除指针以外的变量。
ANSI C:标准的C语言规范
扩展C : 在ANSI C的基础是进行扩展
#include<stdio.h>
int main()
{
printf("%d\n", sizeof(void)); //1
return 0;
}
上面的代码,在ANSI C编译器中是无法通过编译的,但是在支持GNU标准的GCC编译器中确实合法的。
void指针的意义:
C语言规定,只有相同类型的指针才可以互相赋值;
void*指针作为左值,可以接收任意类型的指针;
void*指针作为右值,使用时需要进行强制类型转换。
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; //opps!
void*在指针类型中是一个更大的类型,可以接收更大的类型(左值)。
实例分析:通过void*实现memset函数:
//设置一段内存为指定的值;接收任意类型的指针;
//不用管这一段内存到底是被什么类型的指针指向
#include<stdio.h>
//void* src //接收任意类型的指针 右值
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), 's');
for(i=0; i<5; i++)
{
printf("%c\n", a[i]);
}
return 0;
}
在Linux下使用gcc进行编译运行,结果如下:
delphi@delphi-vm:~/will$ gcc test.c
delphi@delphi-vm:~/will$ ./a.out
s
s
s
s
s
更改mian()函数:
int main()
{
int a[5];
int i=0;
MemSet(a, sizeof(a), 0);
for(i=0; i<5; i++)
{
printf("%f\n", a[i]);
}
return 0;
}
运行结果如下:
delphi@delphi-vm:~/will$ gcc test.c
delphi@delphi-vm:~/will$ ./a.out
0.000000
0.000000
0.000000
0.000000
0.000000
小结:
在C语言中,goto语句是被禁用的;
void是一种抽象的数据类型,且不能用于定义变量;
void类型用于声明函数五参数和声明函数无返回值;
可以定义void*类型的指针,这个指针可以接受任意类型的指针。(memcpy、memset等)