3.4 goto语句的使用及注意事项
goto语句也称为无条件转移语句。值得注意的是,goto语句只能在函数内部进行转移,不能够跨越函数。goto语句使用的一般格式为:
goto语句标号;
……
语句标号:
或者
语句标号:
……
goto语句标号;
其中,语句标号是goto语句转向的目标。注意,目标处的语句标号后有“:”;语句标号的命名要遵循C语言的命名规则。下面先来看看如何使用goto语句建立循环,下面的代码实现了1到100之间所有整数的累加和。
include<stdio.h>
void main(void)
{
int num,i;
int sum;
num=0;
sum=0;
loop:
sum+=num;
num++;
if(num<101)
goto loop;
printf("使用goto语句建立循环求得的sum=%d\n",sum);
sum=0;
for(i=0;i<101;i++)
{
sum+=i;
}
printf("使用for循环求得的sum=%d\n",sum);
return;
}
运行结果:
使用goto语句建立循环求得的sum=5050
使用for循环求得的sum=5050
从运行结果来看,goto语句建立的循环和for循环计算出来的结果完全相同。goto语句不仅可以实现循环体的设计,还可以用于多层循环体的退出。接下来查找一个四位数中的最小的水仙花数,其代码为:
include<stdio.h>
void main(void)
{
int i,j,k,f;
int num;
for(i=1;i<=9;i++)
for(j=0;j<=9;j++)
for(k=0;k<=9;k++)
for(f=0;f<=9;f++)
{
num=i1000+j100+k*10+f;
if(num==(iiii+jjjj+kkkk+ffff))
{
printf("%d\n",num);
goto exit;
}
}
exit:
return;
}
运行结果:
1634
在上面的四重循环中,使用goto语句跳出循环体使代码显得很简洁,如果不使用goto语句来跳出循环体,那么就要在每个for循环中使用满足条件时的退出语句。但是,千万不能在编程中随便使用goto语句,因为goto语句会使代码的可读性大大降低和难以控制,而且稍有不慎还可能导致程序崩溃。下面一段代码的功能为创建一个动态数组,数组元素的个数由n来确定,对数组中的每个元素赋初值,然后输入一个数n1,打印出数组中前n1个元素。
include<stdio.h>
include<stdlib.h>
void main(void)
{
int n,n1,i;
printf("请输入所要分配的大小:");
scanf("%d",&n);
intarr=(int)malloc(sizeof(int)*n);
int*p;
for(i=0;i<n;i++)
{
arr[i]=i+1;
}
printf("请输入所要打印的数字元素个数:");
scanf("%d",&n1);
if(n1>n)
goto exit;
p=arr;
for(i=0;i<n1;i++)
printf("p[%d]=%d\t",i,p[i]);
int a;
exit:
free(p);
return;
}
如果输入的所要打印的数组元素的个数大于所分配的大小,那么就使用goto语句跳过打印部分。下面分析一下上述代码的运行是否有问题。
当输入的打印数组元素个数不大于分配的个数时,运行结果如下:
请输入所要分配的大小:5
请输入所要打印的数字元素个数:5
p[0]=1 p[1]=2 p[2]=3 p[3]=4 p[4]=5
当输入的所要打印的数组元素个数大于分配的个数时,我们发现程序直接崩溃了。为什么会出现这样的情况呢?这是因为使用goto语句跳过了对整型指针p赋值的语句“p=arr;”。由于p是一个空指针,不允许使用free()函数,否则会导致程序崩溃。
因此,读者在编程时要慎用goto语句,不到迫不得已不要使用goto语句,如果用了goto语句,要在其旁边写出详细的注释。