C语言进阶:8、goto和void分析

禁用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语言规范

扫描二维码关注公众号,回复: 146217 查看本文章

扩展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等)



猜你喜欢

转载自blog.csdn.net/qq_28388835/article/details/80157164