Advanced C language: 8, goto and void analysis

Disable 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); // after goto, the new line of code will not be executed
	
STATUS:
	p[0] = n;
	
	free (p);	
}

intmain()
{
	printf("Begin!\n");
	
	printf("f1(1)\n");
	
	f1 (1);
	
	printf("f1(-1)\n");
	
	f1(-1); //Segmentation fault
	
	printf("end!\n");
	
	return 0;
}

Using Gcc to compile and run the code under linux, the execution is as follows:

delphi@delphi-vm:~/will$ ./a.out
Begin!
f1 (1)
f1 (-1)
segfault

The goto language breaks the sequential execution structure of the program.

The meaning of void:

            If the function has no return value, declare the function as void;

            If the function has no parameters, declare its parameters as void. (Can not be empty)

The purpose of void decorating function return values ​​and parameters is to represent "nothing".

Observe the following code to experience the role of void:

f1() //Can accept any number of parameters, the return value defaults to int
{
}

void f2 (void) // does not accept parameters, no return value
{
}

intmain()
{
	int i=f1(1, 2, 3);
 
	return 0;
}

have to be aware of is:

There is no void variable - the C language does not define how much memory void occupies;

Observe the following code:

#include<stdio.h>

intmain()
{
	void i;  //error
	void array[];  //error
	void *p; //right   void can be used to declare pointers.
	
	return 0;
}

It can be found that variables other than pointers cannot be declared with void.

ANSI C: Standard C Language Specification

Extended C: The basis of ANSI C is extended

#include<stdio.h>

intmain()
{
	printf("%d\n", sizeof(void));  //1
	
	return 0;
}

The above code will not compile in the ANSI C compiler, but it is indeed legal in the GCC compiler that supports the GNU standard.

The meaning of void pointer:

         The C language stipulates that only pointers of the same type can be assigned to each other;

          As an lvalue, void* pointer can receive pointers of any type;

          The void* pointer is used as an rvalue, and it needs to be casted when using it.

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* is a larger type in pointer types and can receive larger types (lvalues).

Example analysis: implement the memset function through void*:

//Set a piece of memory to the specified value; receive a pointer of any type;
//Don't care what type of pointer this piece of memory is pointing to
#include<stdio.h>

//void* src //Receive any type of pointer rvalue

void MemSet(void* src, int length, unsigned char n)   //Indicates that this function can accept any type of pointer
{
	unsigned char* p = (unsigned char*)src;       //Rvalue. casts the accepted pointer
	
	int i=0;
	
	for(i=0; i<length; i++)
	{
		p[i] = n;
	}
}

intmain()
{
	int a[5];
	int i=0;
	
	MemSet(a, sizeof(a), 's');
	
	for(i=0; i<5; i++)
	{
		printf("%c\n", a[i]);
	}
	
	return 0;
}

Compile and run using gcc under Linux, the results are as follows:

delphi@delphi-vm:~/will$ gcc test.c
delphi@delphi-vm:~/will$ ./a.out
s
s
s
s
s

Change the main() function:

intmain()
{
	int a[5];
	int i=0;
	
	MemSet(a, sizeof(a), 0);
	
	for(i=0; i<5; i++)
	{
		printf("%f\n", a[i]);
	}
	
	return 0;
}

The results are as follows:

delphi@delphi-vm:~/will$ gcc test.c
delphi@delphi-vm:~/will$ ./a.out
0.000000
0.000000
0.000000
0.000000
0.000000

summary:

In C, the goto statement is disabled;

void is an abstract data type and cannot be used to define variables;

The void type is used to declare the five parameters of the function and to declare that the function has no return value;

You can define pointers of type void*, which can accept pointers of any type. (memcpy, memset, etc.)



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325568018&siteId=291194637