Lesson 02: Fundamentals
Welcome to the second lesson in Programming in C. In this
lesson, you will learn about variables, data types, constants, and
literals, which are fundamental concepts for writing C
programs.
Objectives
By the end of this lesson, you should be able to:
- Understand and declare variables in C.
- Identify and use various data types in C.
- Define and use constants in C.
- Differentiate and use various literals, including integers,
floating-point numbers, characters, and strings.
Data Types
Data types specify the type of data that a variable can hold. In
C, the data type of a variable determines the amount of memory
allocated for it and the type of operations that can be performed
on it.
Basic
Data Types
- int: Used for integer values.
- Typical size: 4 bytes
- Format specifier:
%d
- float: Used for single-precision floating-point values.
- Typical size: 4 bytes
- Format specifier:
%f
- double: Used for double-precision floating-point values.
- Typical size: 8 bytes
- Format specifier:
%lf
- char: Used for single characters.
- Typical size: 1 byte
- Format specifier:
%c
int age = 25;
float salary = 50000.50;
double large_number = 123456789.123456789;
char initial = 'A';
printf("age = %d\n", age);
printf("salary = %f\n", salary);
printf("large_number = %lf\n", large_number);
printf("initial = %c\n", initial);
Extended Data Types
- short int: Used for smaller integer values.
- Typical size: 2 bytes
- Format specifier:
%hd
- unsigned int: Used for non-negative integer values.
- Typical size: at least 2 bytes, usually 4 bytes
- Format specifier:
%u
- long int: Used for larger integer values.
- Typical size: at least 4 bytes, usually 8 bytes
- Format specifier:
%ld , %li
- long long int: Used for even larger integer values.
- Typical size: at least 8 bytes
- Format specifier:
%lld , %lli
- unsigned long int: Used for non-negative large integer
values.
- Typical size: at least 4 bytes, usually 8 bytes
- Format specifier:
%lu
- unsigned long long int: Used for very large non-negative
integer values.
- Typical size: at least 8 bytes
- Format specifier:
%llu
- signed char: Used for small integer values, typically
from -128 to 127.
- Typical size: 1 byte
- Format specifier:
%hhd (integer value),
%c (character)
- unsigned char: Used for small non-negative integer
values, typically from 0 to 255.
- Typical size: 1 byte
- Format specifier:
%hhu (integer value),
%c (character)
- long double:
- Typical size: 10 bytes, 12 bytes or 16 bytes
- Format specifier:
%Lf
Depending on which compiler you use and how it is configured,
incorrect usage of signed and unsigned variables may trigger
warnings or even errors.
/* valid usage */
unsigned int x = 42;
signed int y = -42;
/* invalid usage, but compilable */
unsigned int z = -42; /* unsigned negative value */
printf("%u\n", x); /* this will print 42 */
printf("%d\n", y); /* this will print -42 */
printf("%u\n", z); /* this will NOT print -42, but 4294967254 */
Typedef: Creating
Aliases
The typedef keyword allows you to create new names
(aliases) for existing data types, but does not (usually) create a
new type. This can make your code more readable and easier to
manage.
typedef unsigned long ulong;
ulong distance = 1000000;
In this example, ulong is an alias for
unsigned long , making the code more concise and easier
to read.
A typedef may be used to simplify declarations of
objects such as struct , union , or pointer
types. Enums, structs and unions will be explained in later
lessons, but here’s a quick example:
typedef enum {
RED,
GREEN,
BLUE
} Color;
typedef struct {
int x;
int y;
} Point;
In this example, Color is an alias for an
enumeration of color values, and Point is an alias for
a structure representing a point in a 2D space. As such,
Color and Point can now be used as data
types for specifying variables:
Color favorite_color = RED;
Point point_a = {10, 20};
Literals
Literals represent fixed values used directly in the code. They
can be of different types, including integers, floating-point
numbers, characters, and strings. Unlike variables, literals cannot
change and are hard-coded into the program.
Integer
Literals
Integer literals are whole numbers without a decimal point. They
can, depending on the compiler, be specified in decimal (base 10),
octal (base 8), hexadecimal (base 16), or binary (base 2)
formats.
int decimal = 10; /* Decimal (base 10) */
int octal = 012; /* Octal (base 8) */
int hex = 0xA; /* Hexadecimal (base 16) */
int bin = 0b0101; /* Binary (base 2) */
Floating-Point Literals
Floating-point literals represent numbers with a fractional
part. They can be written with or without an exponent.
float f = 3.14f; /* Single-precision floating-point */
double d = 3.14; /* Double-precision floating-point */
float sf = 1.23e5; /* using exponent: 1.23 * 10^5 */
double sd = 4.56e-2; /* using exponent: 4.56 * 10^-2 */
Character Literals
Character literals are enclosed in single quotes and represent a
single character. They can also represent ASCII values.
char letter = 'A';
char newline = '\n'; /* Escape sequence for new line */
String
Literals
String literals are enclosed in double quotes and represent a
sequence of characters. They are stored as arrays of characters
terminated with a null character ( ). The format specifier for
string literals is %s .
char greeting[] = "Hello, World!";
char *multiline_str = "This is a multi-line\n" /* using a pointer */
"string literal\n"
"in C.";
const char *str = R"(
This is a raw string literal.
It can contain multiple lines and special characters like \t and \n.
No need to escape quotes ("), backslashes (\), or other characters.)";
It is important to note that raw string literals (R"...") are
not standard in C (up to C11). They are a feature introduced in
C++11 and later versions of C++. Depending on your compiler, raw
string literals could be undefined. You can also use different
delimiters in raw string literals R"delim(...delim) as
long as delim does not appear in the raw_characters
section.
Escape
Sequences
Escape sequences are used to represent special characters within
string and character literals, that otherwise have specific
functions. They start with a backslash (\).
\a : Alert (bell) character
\b : Backspace
\e : Escape character
\f : Form feed
\n : Newline
\r : Return
\t : Horizontal tab
\v : Vertical tab
\\ : Backslash
\' : Single quote
\" : Double quote
\? : Question mark
\0 : Null character
\nnn : Octal representation, represents the
character with the ASCII code specified by up to three octal digits
nnn.
\xhh : Hexadecimal representation, represents the
character with the ASCII code specified by exactly two hexadecimal
digits hh.
\uxxxxxxxx : Universal character name in
hexadecimal notation (C99 and later), represents a Unicode
character specified by the hexadecimal number xxxxxxxx.
\u{xxxx} : Universal character name in hexadecimal
notation (C11 and later), represents a Unicode character specified
by the Unicode code point in {xxxx}.
#include <stdio.h>
int main() {
printf("Horizontal tab: \t\n");
printf("Escape character: \e\n");
printf("Escape character (hex): \x1b\n");
printf("Greek capital letter Omega: \u03A9\n");
printf("Unicode smiley face emoji: \u0001F600\n");
return 0;
}
Variables
Variables are used to store data that can be manipulated by a
program. Each variable in C must be declared with a specific data
type before it can be used. Variables can hold different types of
data such as integers, floating-point numbers, characters, etc.
Declaring Variables
To declare a variable, specify the data type followed by the
variable name:
int age;
float salary;
char initial;
Initializing Variables
Variables can be initialized at the time of declaration. The
value assigned to the variable at the time of declaration is known
as the literal, which is always placed on the right side of the
equal sign.
int age = 25;
float salary = 50000.50;
char initial = 'A';
In this case, 25 , 50000.50 , and
'A' are literals, while age, salary, and initial are
the variables. Variables can change values during the execution of
a program, whereas literals are fixed values. Previously declared
and/or initialized variables can have new values assigned to them.
This is not an initialization but rather a reassignment or update
of the variable’s value. A new literal is then assigned to the
variable.
int age = 25; /* correct: variable declaration and initialization */
age = 35; /* correct: variable assignment */
45 = age; /* incorrect */
24 = 42; /* incorrect */
int age = 25; is both a declaration and an
initialization of the variable age .
age = 35; is an assignment or rather reassignment
of the variable age with a new literal 35.
45 = age; is an incorrect assignment. Literals
(like 45) cannot be on the left-hand side of an assignment
because they are fixed values.
24 = 42; Both 24 and 42 are
literals, and neither can be assigned to the other. Literals cannot
be on the left-hand side of an assignment because they represent
fixed values.
Using
Variables
Variables can be used in expressions, passed as arguments to
functions, and manipulated in various ways. This is just a simple
example:
int age = 35;
int years = 5;
int total_age = age + years; /* Using variables in an expression */
printf("Total Age: %d\n", total_age); /* Output the result: 'Total age: 40' */
Constants
Constants are values that, much like literals, cannot be changed
once assigned. They are, similarly to variables, declared but using
the const keyword. Constants are useful for defining fixed values
that should not be altered during program execution.
Declaring Constants
const int DAYS_IN_WEEK = 7;
const float PI = 3.14159;
const char NEWLINE = '\n';
C also allows for macros to be used for declaring constant
values for the compiler. Macros will be covered in a later
lesson.
Using
Constants
Constants are used in the same way as variables but cannot be
modified after their initial assignment:
printf("There are %d days in a week.\n", DAYS_IN_WEEK);
printf("The value of PI is approximately %.5f\n", PI);
Exercises
- Declare and Initialize Variables: Create variables of
different types and initialize them with appropriate values.
- Using Constants: Declare constants for the number of
days in a week and the value of Pi. Use them in appropriate print
statements. Try using a macro with
#define .
- Understanding Literals: Write a program that
demonstrates the use of integer, floating-point, character, and
string literals. Use
printf(...); in your
demonstration.
- ’Deux et deux font cinq’: The statement ’Deux et deux
font cinq’ (’Two and two make five’) represents a mathematical
falsehood, often cited as a simple example of a logical error that
contradicts basic arithmetic principles. This phrase has been used
in various contexts, notably in George Orwell’s novel ’Nineteen
Eighty-Four,’ where it symbolizes the distortion of truth and the
power of propaganda.
While inherently untrue in standard arithmetic, ’Deux et deux
font cinq’ has also sparked artistic and philosophical
explorations. It predates Orwell’s novel, appearing in works such
as Alphonse Allais’ absurdist short stories and Vadim
Shershenevich’s imagist art manifesto, where it challenges
conventional thinking and invites reflection on the limits of
rationality.
In this exercise, you will explore the concept of ’Deux et deux
font cinq’ through the lens of programming with C. By examining how
data types, operations sequence, and variable manipulations can
affect computational outcomes, the aim is to illustrate the
precision required in programming logic and highlight the
implications of deviating from mathematical norms.
Rewrite the following program so that it prints mathematically
correct statements.
#include <stdio.h>
int main() {
int i5 = 5;
int i4 = 4;
printf("%d / %d = %d0, i5, i4, i5 / i4); /* 5 / 4 = 1.25 (?) */
printf("%d * %d = %d0, i5 / i4, 2, i5 / i4 * 2); /* 1.25 * 2 = 2.5 (?) */
printf("%d + %d = %d0, i5 / i4 * 2, i5 / i4 * 2, i5); /* 2.5 + 2.5 = 5 (?) */
printf("Deux et deux font cinq!0);
return 0;
}
Solutions
Example solution to ’Declare and Initialize Variables’:
#include <stdio.h>
int main() {
int age = 25;
float height = 5.9;
char initial = 'A';
printf("Age: %d0, age);
printf("Height: %.1f0, height);
printf("Initial: %c0, initial);
return 0;
}
Example solution to ’Using Constants’:
#include <stdio.h>
#define PI 3.14159
int main() {
const int DAYS_IN_WEEK = 7;
printf("There are %d days in a week.0, DAYS_IN_WEEK);
printf("The value of PI is approximately %.5f0, PI);
return 0;
}
Example solution to ’Understanding Literals’:
#include <stdio.h>
int main() {
int decimal = 10;
float pi = 3.14f;
char letter = 'A';
char greeting[] = "Hello, World!";
printf("Integer literal: %d0, decimal);
printf("Floating-point literal: %.2f0, pi);
printf("Character literal: %c0, letter);
printf("String literal: %s0, greeting);
return 0;
}
Example solution to ’Deux et deux font cinq’:
#include <stdio.h>
int main() {
float f5 = 5;
float f4 = 4;
printf("%0.0f / %0.0f = %0.2f0, f5, f4, f5 / f4);
printf("%0.2f * %d = %0.1f0, f5 / f4, 2, f5 / f4 * 2);
printf("%0.1f + %0.1f = %0.0f0, f5 / f4 * 2, f5 / f4 * 2, f5);
return 0;
}
Next Lesson
In the next lesson, we will delve deeper into Input/Output (I/O)
operations in C. We will cover techniques for handling input from
users and files, using functions like printf ,
scanf , fprintf , and fscanf .
This knowledge will enable you to create programs that interact
with users and manage data through file operations.
Next Lesson
|