Getting Started

Getting Started

// hello_world.c
#include <stdio.h>

int main(int argc, char *argv[])
{
    printf("hello, world\n");
    return 0;
}

Variables and Arithmetic Expressions

// f_to_c.c
#include <stdio.h>

/* print Fahrenheit-Celsius table for fahr = 0, 20, ..., 300 */
int main(int argc, char *argv[])
{
    float fahr = 0;    /* Temperature in Fahrenheit */
    float celsius = 0; /* Temperature in Celsius */
    int lower = 0;   /* Lower limit of temperature table */
    int upper = 300;   /* Upper limit of temperature table */
    int step = 20;    /* Step size */
    
    fahr = lower;
    while (fahr <= upper)
    {
        celsius = (5.0 / 9.0) * (fahr - 32.0);
        printf("%3.0f\t%6.1f\n", fahr, celsius);
        fahr += step;
    }

    return 0;
}

Data Types:

  • char: 1 byte

  • short: 2 bytes

  • long: 4 bytes

  • double: 8 bytes

Format:

  • %d: print as decimal integer

  • %6d: print as decimal integer, at least 6 characters wide

  • %f: print as floating point

  • %6f: print as floating point, at least 6 characters wide

  • %.2f: print as floating point, 2 characters after decimal point

  • %6.2f: print as floating point, at least 6 wide and 2 after decimal point

For Statement

// f_to_c_for_loop.c
#include <stdio.h>

/* print Fahrenheit-Celsius table */
int main(int argc, char *argv[])
{
    for (int fahr = 0; fahr <= 300; fahr += 20)
    {
        printf("%3d %6.1f\n", fahr, (5.0 / 9.0) * (fahr - 32));
    }

    return 0;
}

Symbolic Constants

// f_to_c_constants.c
#include <stdio.h>

#define LOWER 0 /* Lower limit of table */
#define UPPER 300 /* Upper limit of table */
#define STEP 20 /* Step size */

/* print Fahrenheit-Celsius table */
int main(int argc, char *argv[])
{
    for (int fahr = LOWER; fahr <= UPPER; fahr += STEP)
    {
        printf("%3d %6.1f\n", fahr, (5.0 / 9.0) * (fahr - 32));
    }

    return 0;
}

Character Input and Output

File Copying

// file_copying.c
#include <stdio.h>

/* copy input to output */
int main(int argc, char *argv[])
{
    int c = 0;

    while ((c = getchar()) != EOF)
    {
        putchar(c);
    }
    
    return 0;
}

Precedence:

The precedence of != is higher than that of =, so the following statements are equivalent

  • c = getchar() != EOF

  • c = (getchar() != EOF).

The semantic is very different from (c = getchar()) != EOF.

Character Counting

// character_counting.c
#include <stdio.h>

/* count characters in input */
int main(int argc, char *argv[])
{
	double nc;

	for (nc = 0; getchar() != EOF; ++nc)
	{
		;
	}
	printf("%.0f\n", nc);

	return 0;
}

Line Counting

// line_counting.c
#include <stdio.h>

/* count lines in input */
int main(int argc, char *argv[])
{
	int c = 0; /* Input character */
	int nl = 0; /* Number of lines */

	while ((c = getchar()) != EOF)
	{
		if (c == '\n')
		{
			++nl;
		}
    }
	printf("%d\n", nl);

    return 0;
}

Word Counting

// word_counting.c
#include <stdio.h>

#define IN 1 /* Inside a word */
#define OUT 0 /* OUtside a word */

/* count lines, words, and characters in input */
int main(int argc, char *argv[])
{
	int c = 0; /* Input character */
	int nl = 0; /* Number of lines */
	int nw = 0; /* Number of words */
	int nc = 0; /* Number of characters */
	int state = 0; /* Inside or outside a word */

	state = OUT;
	while ((c = getchar()) != EOF)
	{
		++nc;

		if (c == '\n')
		{
			++nl;
		}
		else if (c == ' ' || c == 'n' || c == 't')
		{
			state = OUT;
		}
		else if (state == OUT)
		{
			state = IN;
			++nw;
		}
	}

    printf("Number of lines: %d\n", nl);
    printf("Number of words: %d\n", nw);
    printf("Number of characters: %d\n", nc);

    return 0;
}

Arrays

// arrays.c
#include <stdio.h>

/* count digits, white space, others */
int main(int argc, char *argv[])
{
	int c = 0;
	int i = 0;
	int nwhite = 0;
	int nother = 0;

	int ndigit[10] = {0};

	while ((c = getchar()) != EOF)
	{
		if (c >= '0' && c <= '9')
		{
			++ndigit[c - '0'];
		}
		else if (c == ' ' || c == '\n' || c == '\t')
		{
			++nwhite;
		}
		else
		{
			++nother;
		}
	}

	printf("digits =");
	for (i = 0; i < 10; i++)
	{
		printf(" %d", ndigit[i]);
	}
	printf(", white space = %d, other = %d\n",
		nwhite, nother);
}

Functions

// power.c
#include <stdio.h>

// Function prototype
int power(int m, int n);

/* test power function */
int main(int argc, char *argv[])
{
	for (int i = 0; i < 10; ++i)
	{
		printf("%d %d %d\n", i, power(2, i), power(-3, i));
	}

    return 0;
}

/* power: raise base to n-th power; n >= 0 */
int power(int base, int n)
{
	int p = 1;

	for (int i = 0; i <= n; ++i)
	{
		p *= base;
	}

	return p;
}

Arguments-Call by Value

In C, all function arguments are passed "by value". This means that the called function is given the values of its arguments in temporary variables rather than the originals. This leads to some different properties than are seen with "call by reference" languages like Fortran or with var parameters in Pascal, in which the called routine has access to the original argument, not a local copy.

Character Arrays

In C, strings are represented by char arrays. Every char array is terminated by a null byte (\0). For example, a string constant like "hello\n" is stored in memory as in the following diagram:

Below is a sample program that takes input and prints out the longest line:

// longest_line.c
#include <stdio.h>

#define MAXLINE 1000 /* Maximum input line size */

int get_line(char line[], int maxline);
void copy(char to[], char from[]);

/* print longest input line */
int main(int argc, char *argv[])
{
	int len = 0; /* Current line length */
	int max = 0; /* Maximum length seen so far */
	char line[MAXLINE] = {0}; /* Current input file */
	char longest[MAXLINE] = {0}; /* Longest line saved here */

	while ((len = get_line(line, MAXLINE)) > 0)
	{
		if (len > max)
		{
			max = len;
			copy(longest, line);
		}
	}

	if (max > 0)
	{
		printf("%s", longest);
	}

	return 0;
}

/* get_line: read a line into `s`, return `length` */
int get_line(char s[], int lim)
{
	int c = 0;
	int i = 0;

	for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
	{
		s[i] = c;
	}

	if (c == '\n')
	{
		s[i] = c;
		++i;
	}

	s[i] = '\0';

	return i;
}

/* copy: copy `from` into `to`; assume `to` is big enough */
void copy(char to[], char from[])
{
	int i = 0;

	while ((to[i] = from[i]) != '\0')
	{
		++i;
	}
}

External Variables and Scope

In C, local variables are called "automatic variables". If you wish local variables retain their values between calls, use the static keyword.

In C, global variables are called "external varaibles". An external variable must be defined, exactly once, outside of any function; this sets aside storage for it. The variable must also be declared in each function that wants to access it; this states the type of the variable. The declaration may be an explicit extern statement or may be implicit from context.

Below is an updated version of longest_line.c which shows the usage of external variables:

// longest_line_extern.c
#include <stdio.h>

#define MAXLINE 1000 /* Maximum input line size */

int max = 0; /* Maximum length seen so far */
char line[MAXLINE] = {0}; /* Current input file */
char longest[MAXLINE] = {0}; /* Longest line saved here */

int get_line(void);
void copy(void);

/* print longest input line; specialized version */
int main(int argc, char *argv[])
{
	int len = 0; /* Current line length */
	extern int max;
	extern char longest[];

	while ((len = get_line()) > 0)
	{
		if (len > max)
		{
			max = len;
			copy();
		}
	}

	if (max > 0)
	{
		printf("%s", longest);
	}

	return 0;
}

/* get_line: specialized version */
int get_line(void)
{
	int c = 0;
	int i = 0;
	extern char line[];

	for (i = 0; i < MAXLINE - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
	{
		line[i] = c;
	}

	if (c == '\n')
	{
		line[i] = c;
		++i;
	}

	line[i] = '\0';

	return i;
}

/* copy: specialized version */
void copy(void)
{
	int i = 0;
	extern char line[];

	while ((longest[i] = line[i]) != '\0')
	{
		++i;
	}
}

Last updated