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语句,要在其旁边写出详细的注释。