Your First C Program

C · Lesson 3 of 32 9 min read Updated

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.

C
#include <stdio.h>

int main(void)
{
    printf("Hello, Kochi!\n");
    return 0;
}
Output
Hello, Kochi!

Here is what each part does:

  • #include <stdio.h> asks the preprocessor to insert the contents of the header file stdio.h ("standard input and output"). That file declares printf, which means it tells the compiler that printf exists 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 called main. Every C program begins running at main. The int before the name says that main gives back a whole number when it finishes, and void inside 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 the printf function with a string literal, text inside double quotes. The pair \n is an escape sequence that means "new line". The semicolon ends the statement.
  • return 0; ends main and 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:

Terminal
gcc -std=c23 -Wall -Wextra -pedantic hello.c -o hello
./hello

Each part of the compile command has a job:

PartMeaning
gccRun the GCC compiler (use clang instead if that is your compiler)
-std=c23Compile using the C23 standard
-WallTurn on the most useful warnings
-WextraTurn on extra warnings that catch more mistakes
-pedanticWarn when code uses compiler-only extensions instead of standard C
hello.cThe source file to compile
-o helloName 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 */.
C
/*
 * 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;
}
Output
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:

C
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:

C
#include <stdio.h>

int main(void)
{
    printf("Hello, Kochi!\n")
    return 0;
}
Output
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:

C
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.

C
#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):

Terminal
gcc -std=c23 -Wall -Wextra check.c -o check
./check
echo $?
Output
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. Printf or Main are different names from printf and main.
  • 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> makes printf available; 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; (or EXIT_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
C
/* 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
}
Output
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?

2. What does return 0; at the end of main mean?

3. Which comment is written correctly?

4. Which compiler option names the output program report?

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