Goto And Return Statements in C
Goto statement
The goto statement is a leap statement that modifies the typical sequential flow of program execution. It transfers control to another area of the program or makes an unconditional leap.
A label is used in the goto statement’s syntax:
- A labelled statement is the jump’s target.
- An identification followed by a colon (:) is called a label.
- The statement to which control is passed must have the label right before it.
- The term goto, the name of the label, plus a semicolon make up the goto statement itself: goto label;.
- The function must have both the goto statement and the labelled statement that goes with it. Label names don’t have to be distinct for each function.
This code example shows how to use goto to end a loop when a specific condition is met. It is comparable to examples in and:
#include <stdio.h>
int main(void) {
int i;
printf("Starting loop...\n");
for (i = 0; i < 10; ++i) {
// Print value only if it's not 5
if (i == 5) {
// Unconditional jump out of the loop
goto end_loop; // Transfer control to the 'end_loop' label
}
printf("i = %d\n", i);
}
end_loop: // This is the label
printf("Exited loop. i is now %d\n", i); // Execution continues here
return 0;
}
Output:
Starting loop...
i = 0
i = 1
i = 2
i = 3
i = 4
Exited loop. i is now 5
In this example, the program skips the remaining loop iterations and jumps straight out of the for loop to the line that follows the end_loop: label when the goto end_loop; statement is placed inside the if (i == 5) block. Other examples, such as hopping over statements, establishing a loop, and exiting a loop, also demonstrate this.
The goto statement has a poor reputation in contemporary programming and is typically avoided, despite its capacity to change program flow. Its careless use was thought to be the cause of a lot of software development issues. “Goto elimination” has become nearly synonymous with structured programming, which prioritises sequence, selection (if, switch), and iteration (while, do-while, for).
The following are the main justifications for avoiding goto:
- Non-structured coding is encouraged.
- It may compromise the beneficial structure that switches and loops offer.
- It can cause control flow to become erratic and makes programs more difficult to understand.
- Frequently referred to as “spaghetti code” in jest, the use of several gotos can render programs unintelligible.
- It may be more difficult to debug and alter programs that use goto.
- It is not regarded as a component of excellent programming.
- Goto rarely has a valid purpose in well-written code since other control statements are nearly always a more elegant method to organise the code. Usually, you can use the same reasoning without it. Additionally, the excessive usage of goto statements is not recommended or good programming practice because it impairs program performance.
Although goto is typically not recommended, Point to specific situations in which it might be useful, like escape from if statements or deeply nested loops. Some contend that it can streamline the reasoning or perhaps greatly increase the program’s efficiency in certain particular, well-documented situations. While break would just leave the switch, it can also be used to exit loops from within a switch statement. CERT guidelines also suggest taking goto chains into account when addressing errors that require resource cleanup. It is generally agreed upon, however, that the goto keyword should be avoided and that it is safe to employ the “not at all” recommendation.
You can also read A Complete Guide For C Iteration Statements With Examples
Return statement
A function can be terminated and control returned to the point at which it was called by using the return statement. The function’s execution ends instantly when a return statement is executed, and any statements that come after the return are not carried out.
A single value can also be passed back to the calling function from the called function using the return statement.
The return statement is available in two primary forms:
Return;: In functions that don’t return a value, this form is utilised. These functions are defined with a return type of void. Without a return statement, reaching the closing right brace } of a void function also exits the function without returning a value, which is the same as running return;.
return expression;: In functions that are declared to return a value, this form is utilised. The caller receives the value of the expression back. The expression may or may not be enclosed in parenthesis. The expression should return a value whose data type is the same as or convertible to the return type given in the function declaration.
An example of code illustrating both types is provided here:
#include <stdio.h> // Required for printf
// Function that does not return a value (void return type)
// It prints a message.
void printMessage() // Declared with void return type
{
printf("Hello from printMessage!\n");
return; // Optional return statement for void functions
// Code here would not be executed
}
// Function that returns an integer value
// It takes two integers and returns their sum.
int sum(int a, int b) // Declared with int return type
{
int result = a + b;
return result; // Returns the value of the expression 'result'
// Code here would not be executed
}
// Function that returns a boolean-like integer (0 or 1) based on a condition
// It takes an integer and returns 1 if it's prime, 0 otherwise (as an example pattern)
// This shows how multiple return statements can be used
int isPrime(int n)
{
if (n <= 1)
{
return 0; // Returns 0 for non-prime (or invalid) input
}
for (int i = 2; i * i <= n; ++i)
{
if (n % i == 0)
{
return 0; // Returns 0 if divisible by any number other than 1 and itself
}
}
return 1; // Returns 1 if no divisors found (it's prime)
}
int main() // main is a function where program execution begins
{
// Call the function that doesn't return a value
printMessage(); // Control transfers to printMessage(), then returns here
// Call the function that returns a value and store the result
int total = sum(5, 7); // The value returned by sum(5, 7) (which is 12) is assigned to total
printf("The sum is: %d\n", total);
// Call the function that returns a value and use it directly
printf("Is 7 prime? %d\n", isPrime(7)); // The value returned by isPrime(7) is used as an argument to printf
printf("Is 10 prime? %d\n", isPrime(10));
return 0; // main function returns an integer status to the operating system
// Conventionally, 0 indicates successful execution
// A non-zero value indicates an error
}
Output:
Hello from printMessage!
The sum is: 12
Is 7 prime? 1
Is 10 prime? 0
Important details about return:
- Only the first return statement that is seen during execution is handled, even though a function may include several return statements.
- One value at a time is all that a function can return. Although a function can affect several values by using pointers to change variables in the calling function, this is not the same as returning multiple values via the return statement itself.
- The calling function does not have to use the value that a function returns.
- A function in C will default to int if its return type is not explicitly specified.
- The immediate caller regains control after the return statement. This is not the same as exit( ), which ends the program regardless of the function that invokes it. In general, invoking return expression; from main( ) is the same as calling exit(expression) from any function. The _Noreturn specifier is introduced in C11/C18 to designate functions, such as exit, that will expressly not return to their caller.
You can also read A Comprehensive Guide For C Jump Statements