1:先说goto的基本语法
#include<stdio.h>
#include<stdlib.h>
int main()
{
int i = 1;
while(1)
{
printf("在while(1)里\n");
while(i++)
{
printf("i = %d\n",i);
if(i > 3)
{
goto TiaoChu;
}
}
}
TiaoChu:
printf("程序结束\n");
return 0;
}
运行结果:
标号位置
在while(1)里
2
3
4
程序结束
从运行结果我们明显可以知道goto用法,可以跳出多重循环,标号只是标号,程序到标号位置正常执行。
2:goto语句有啥毛病,goto来回这么跳,在程序庞大后,在调试时很难找到错误,所以E.W.Dijikstra在1965年提出结构化程序设计来规避这种错误,也使得代码更容易阅读。
3:goto容易出错,但其仍然有存在的价值,在单个函数中使用goto基本不可能出错,goto在程序反操作上很好用
//函数成功返回1,失败返回0
int fun()
{
FIL *a,*b;//文件体
char *c,*d;
a = fopen("***");
if(a = NULL) return 0;
c = malloc(1000);
if(c = NULL) goto _q1;
b = fopen("***");
if(b = NULL) goto _q2;
d = malloc(1000);
if(d =NULL) goto _q3;
return 1;
q3:
fclose(b);
q2:
free(c);
q1:
fclos(a);
return 0;
}
这种方式很方便的进行了反操作,而不用重复的去几次反操作。
我的实际例子:
/*
*函数功能:返回图片信息结构体p_inf
* 参数:图片路径字符串picture_file_path
* 返回值:返回图片信息,NULL时为读取图片信息失败
* 作者:杨康
*/
p_inf *readPicInf(char *pfilepath)
{
FIL fileDescriptor;//文件体或者称文件描述符
uint32_t readByteResult;//作为f_read的最后一个参数,接受读到了多少个字节
char fOptResult;//接受文件操作返回值(也就是返回结果)
p_inf *infReturn;//图片信息结构体,最后作为返回值
fOptResult = f_open(&fileDescriptor, (const TCHAR*)pfilepath, FA_READ);
if ((fOptResult != FR_OK) || (fileDescriptor.obj.objsize > BMPMEMORYSIZE)) return NULL;
infReturn = (p_inf *)malloc(sizeof(p_inf));
if (infReturn == NULL) goto INFRETURN_MALLOC_ERR;
infReturn->pfilestring = (char *)malloc(fileDescriptor.obj.objsize);
if (infReturn->pfilestring == NULL) goto INFRETURN_PFILESTRING_MALLOC_ERR;
fOptResult = f_read(&fileDescriptor,infReturn->pfilestring,fileDescriptor.obj.objsize, (UINT *)&readByteResult);
if ((fOptResult != FR_OK) || (readByteResult != fileDescriptor.obj.objsize)) goto F_READ_ERR;
infReturn->pfilesize = fileDescriptor.obj.objsize;
f_close(&fileDescriptor);
return infReturn;
F_READ_ERR:
free(infReturn->pfilestring);
INFRETURN_PFILESTRING_MALLOC_ERR:
free(infReturn);
INFRETURN_MALLOC_ERR:
f_close(&fileDescriptor);
return NULL;
}