Your First C Program
Every C program, from a two-line greeting to the Linux kernel, follows the same basic shape. Once you understand the parts of a small program, you can read the structure of any C file.
In this lesson you will write a program, compile it with useful warning options, read error messages, add comments and learn what the number after return means.
The program, line by line
Create a file called hello.c and type this program. Type it rather than copying it; your fingers learn the syntax faster that way.
#include <stdio.h>
int main(void)
{
printf("Hello, Kochi!\n");
return 0;
}Hello, Kochi!
Here is what each part does:
#include <stdio.h>asks the preprocessor to insert the contents of the header filestdio.h("standard input and output"). That file declaresprintf, which means it tells the compiler thatprintfexists and how to call it. Lines starting with#are instructions to the preprocessor, not normal C statements, so they do not end with a semicolon.int main(void)starts the definition of the function calledmain. Every C program begins running atmain. Theintbefore the name says thatmaingives back a whole number when it finishes, andvoidinside the brackets says it takes no inputs.- The braces
{and}mark the body of the function, the block of code that runs. printf("Hello, Kochi!\n");calls theprintffunction with a string literal, text inside double quotes. The pair\nis an escape sequence that means "new line". The semicolon ends the statement.return 0;endsmainand hands the number 0 to the operating system, which means "finished successfully".
Compile and run
Open the terminal in the folder that holds hello.c and run:
gcc -std=c23 -Wall -Wextra -pedantic hello.c -o hello
./helloEach part of the compile command has a job:
| Part | Meaning |
|---|---|
gcc | Run the GCC compiler (use clang instead if that is your compiler) |
-std=c23 | Compile using the C23 standard |
-Wall | Turn on the most useful warnings |
-Wextra | Turn on extra warnings that catch more mistakes |
-pedantic | Warn when code uses compiler-only extensions instead of standard C |
hello.c | The source file to compile |
-o hello | Name the output program hello (hello.exe on Windows) |
Without -o, GCC names the program a.out on Linux and macOS, or a.exe on Windows. If the compiler prints nothing, it succeeded. Every time you change the source code, you must compile again before running; the old program does not update itself.
Comments
A comment is a note for human readers. The compiler ignores it completely. C has two kinds:
//starts a comment that runs to the end of the line./*starts a comment that continues, even across many lines, until*/.
/*
* bill.c: prints the menu of a tea stall in Jaipur.
* Prices are in rupees.
*/
#include <stdio.h>
int main(void)
{
printf("Masala chai: Rs 20\n");
printf("Samosa: Rs 15\n"); // price of one samosa
/* printf("Jalebi: Rs 40\n"); */
return 0;
}Masala chai: Rs 20 Samosa: Rs 15
The jalebi line does not print because it sits inside a comment. Programmers often "comment out" a line like this while testing. Note that /* ... */ comments cannot be nested: the first */ ends the comment, even if another /* appeared inside it.
Good comments explain why the code does something, not what every line does. // add 1 to count above count = count + 1; adds nothing. // the first row of the file is a header is useful.
Statements, blocks and whitespace
A statement is one instruction and ends with a semicolon. A block is a group of statements inside braces. C ignores extra spaces, tabs and line breaks between words, so these two lines mean exactly the same:
printf("Total: %d\n", 42);
printf( "Total: %d\n" , 42 ) ;Even so, keep one statement per line and indent the body of every block by four spaces. Your code will be easier to read and to fix. C is also case-sensitive: printf, Printf and PRINTF are three different names, and only the first one exists.
Reading errors and warnings
When the compiler finds code it cannot understand, it reports an error and does not create a program. Here the semicolon after printf(...) is missing:
#include <stdio.h>
int main(void)
{
printf("Hello, Kochi!\n")
return 0;
}hello.c: In function 'main': hello.c:5:30: error: expected ';' before 'return'
Read the message from the left: the file name, then line 5, column 30, then the problem. GCC also prints the source line with a ^ marker under the exact spot. Newer versions show curly quotes around names; the meaning is the same. Fix the first error first, because one mistake can cause several confusing messages after it.
A warning means the code compiles, but it probably does not do what you meant. For example, %d expects a whole number, so passing 3.5 is wrong:
printf("Average: %d\n", 3.5);With -Wall, GCC says: warning: format '%d' expects argument of type 'int', but argument 2 has type 'double'. The program still builds, but it prints a meaningless number. Treat every warning as a bug to fix. Some teams add -Werror, which turns warnings into errors so they cannot be ignored.
The exit status
The number that main returns is called the exit status. Other programs and scripts read it to know whether your program succeeded. Zero means success; any other value means something went wrong. The header stdlib.h defines two readable names, EXIT_SUCCESS and EXIT_FAILURE.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
printf("Checking exam form...\n");
printf("Roll number missing!\n");
return EXIT_FAILURE;
}In a Linux, macOS or MSYS2 terminal, echo $? prints the exit status of the last program (in PowerShell, use $LASTEXITCODE):
gcc -std=c23 -Wall -Wextra check.c -o check
./check
echo $?Checking exam form... Roll number missing! 1
EXIT_FAILURE is 1 on common systems. If main reaches its closing brace without a return, C99 and later return 0 automatically, but writing return 0; makes your intention clear.
What the compiler does behind the scenes
The single gcc command runs four stages for you. The preprocessor handles #include and other # lines. The compiler proper turns C into assembly language. The assembler turns that into machine code in an object file. Finally the linker joins your object file with the C library, where the real code of printf lives, to produce the executable. You will look at each stage in Header Files & Multi-file Programs.
Common mistakes
- Forgetting a semicolon. The error usually points at the start of the next line, so look just before the reported spot.
- Wrong capital letters.
PrintforMainare different names fromprintfandmain. - Missing
\n. Without it, the next output, or your terminal prompt, appears on the same line. - Curly quotes copied from a chat app or word processor.
“Hello”is not valid C. The compiler reports a "stray" character. Type straight quotes"in your editor. - Running the old program. If your change "did nothing", you probably forgot to compile again.
Key points
- Every C program starts running at
int main(void). #include <stdio.h>makesprintfavailable; preprocessor lines do not end with a semicolon.- Compile with
gcc -std=c23 -Wall -Wextra -pedantic file.c -o name, then run./name. //comments run to the end of the line;/* */comments can span lines but cannot nest.- Errors stop compilation; warnings point at likely bugs and should always be fixed.
return 0;(orEXIT_SUCCESS) means success; a non-zero exit status means failure.
Exercise
Write a program ticket.c that prints this train ticket summary exactly, one item per line: the passenger name Meera Iyer, the route Kochi to Chennai, and the coach and seat B2, Seat 34. Add a comment at the top with the file name and what the program does, and one comment explaining the exit status. Compile it with all the warning options from this lesson.
Show solution
/* ticket.c: prints a short train ticket summary. */
#include <stdio.h>
int main(void)
{
printf("Passenger: Meera Iyer\n");
printf("Route: Kochi to Chennai\n");
printf("Coach: B2, Seat 34\n");
return 0; // 0 tells the operating system that the program succeeded
}Passenger: Meera Iyer Route: Kochi to Chennai Coach: B2, Seat 34
Compile it with gcc -std=c23 -Wall -Wextra -pedantic ticket.c -o ticket and run ./ticket. Each line ends with \n, so each item prints on its own line.
Quick Quiz
1. What does #include <stdio.h> do?
The preprocessor copies the contents of stdio.h into your file, so the compiler knows about printf.
2. What does return 0; at the end of main mean?
An exit status of 0 means success; other values signal an error.
3. Which comment is written correctly?
C uses // for single-line comments and /* */ for comments that can span lines.
4. Which compiler option names the output program report?
-o sets the output file name; without it GCC uses a.out or a.exe.
Learn C with a mentor
Free lessons get you started. Our Java, C & C++ Programming training adds real projects and code reviews from working developers.
- Project-based learning
- Mentor code reviews
- Free counselling call
