Constants
A constant is a value that remains unchanged during program execution.
Categories of constants:
- Literal constantsDirect values included in the source code, e.g.,
10,'A',3.14. const-qualified variables
const int MAX = 100;
These variables occupy memory and are enforced as read-only at runtime.
- Macro constants (via
#define)
#define PI 3.14159
These are handled by the preprocessor and do not consume runtime memory.
Variables
A variable is a named memory location used to store data whose value may change during execution.
Declaration and definition syntax:
type variable_name;
type variable_name = initial_value;
Example:
int age = 25;
float price = 19.99f;
char grade = 'A';
Addisional notes:
- A definition allocates storage, whereas a declaration (e.g.,
extern int r;) does not. - A variable must be defined before use. If only declared (via
extern), the compiler will not promote it to a definition automatically.
Example: Circle Area and Circumference
#include <stdio.h>
#define PI 3.1415
int main(void) {
const int radius = 3;
float area = PI * radius * radius;
float circumference = 2.0f * PI * radius;
printf("Circumference: %.2f\n", circumference);
printf("Area: %.2f\n", area);
return 0;
}
Identifiers
Identifiers are names for variables and constants.
Rules:
- Start with a letter or underscore; digits may follow.
- Case-sensitive:
myVar≠MyVar. - Prefer lowercase for variables, uppercase for constants.
The sizeof Operator
sizeof yields the size (in bytes) of a type or expression. Its result is of type size_t.
#include <stdio.h>
int main(void) {
int i = 0;
short s = 0;
long l = 0;
long long ll = 0;
char c = 'A';
float f = 3.14f;
double d = 3.14;
long double ld = 3.14L;
printf("int: %zu, short: %zu, long: %zu, long long: %zu\n",
sizeof(i), sizeof(s), sizeof(l), sizeof(ll));
printf("float: %zu, double: %zu, long double: %zu\n",
sizeof(f), sizeof(d), sizeof(ld));
printf("char: %zu, void*: %zu\n",
sizeof(c), sizeof(void*));
return 0;
}
Note:
%zuis used forsize_tvalues.
Integer Types
Character Type
The char type holds a single character or byte-sized integer.
Example:
#include <stdio.h>
#include <ctype.h>
int main(void) {
char ch = 'A';
char numChar = '5';
printf("Character: %c\n", ch);
printf("ASCII value: %d\n", ch);
char b = 66;
printf("ASCII 66 → %c\n", b);
printf("Is '%c' alphabetic? %s\n", ch, isalpha(ch) ? "yes" : "no");
printf("Is '%c' a digit? %s\n", numChar, isdigit(numChar) ? "yes" : "no");
printf("Uppercase of 'z': %c\n", toupper('z'));
printf("Lowercase of 'A': %c\n", tolower('A'));
return 0;
}
Notes:
- Characters use single quotes:
'A'; strings use double quotes:"A". charis an 8-bit signed or unsigned integer depending on compiler/platform.
Common Escape Sequences:
Floating-Point Types
Example:
#include <stdio.h>
#include <float.h>
int main(void) {
float f = 3.1415926f;
double d = 3.141592653589793;
printf("f = %.6f, d = %.15f\n", f, d);
// Precision pitfalls
if (0.1 + 0.2 == 0.3) {
printf("Equal\n");
} else {
printf("Unequal due to floating point error\n");
}
printf("FLT_DIG = %d, DBL_DIG = %d\n", FLT_DIG, DBL_DIG);
return 0;
}
Caution:
0.1 + 0.2 != 0.3due to binary floating-point representation.
Number Base Notasion
Note: Binary literals (
0b…) are a GCC/Clang extension, not standard before C23.
Conversion examples:
#include <stdio.h>
int main(void) {
int decimal = 255;
printf("Decimal: %d\n", decimal);
printf("Octal: %o\n", decimal);
printf("Hex (lower): %x\n", decimal);
printf("Hex (upper): %X\n", decimal);
return 0;
}
Number Representation: Sign-Magnitude, One’s Complement, Two’s Complement
- Sign-magnitude (original code): MSB is sign; rest is magnitude.
- One’s complement: Invert bits (except sign) for negatives.
- Two’s complement: One’s complement + 1 (used in most modern systems).
Example (8-bit representation of -5):
- Original:
10000101 - One’s complement:
11111010 - Two’s complement:
11111011
Using two’s complement simplifies arithmetic, avoids multiple zero representations, and enables natural overflow wrapping.
Integer Overflow
Overflow occurs when a value exceeds the representable range.
Example:
#include <stdio.h>
#include <limits.h>
int main(void) {
int max_int = INT_MAX;
printf("INT_MAX: %d\n", max_int);
max_int++; // signed overflow: undefined behavior in C
printf("After increment: %d\n", max_int); // often wraps to INT_MIN
unsigned int max_uint = UINT_MAX;
printf(" UINT_MAX: %u\n", max_uint);
max_uint++;
printf("After increment: %u\n", max_uint); // wraps to 0 (defined for unsigned)
return 0;
}
Warning: signed integer overflow is undefined behavior in standard C. Unsigned overflow wraps modulo 2ⁿ (well-defined).
Floating-point overflow leads to +inf or -inf. Underflow may result in zero.
Type Qualifiers
Example:
static int count = 0;
volatile int sensor_value;
const double E = 2.718281828459045;
Formatted I/O
Output with printf
Function signature:
int printf(const char *format, ...);
Width and precision:
printf("%+6.2f\n", -12.5); // "+ -12.50"
printf("%-10s", "Hi"); // left-aligned, padded
Input with scanf
Function signature:
int scanf(const char *format, ...);
Important notes:
%sreads non-whitespace characters until space/newline; no bounds checking → usefgets()for safety.- After
%c, leftover newline may interfere with subsequent reads.
Comparison: printf vs putchar, scanf vs getchar
Example using putchar:
#include <stdio.h>
int main(void) {
char msg[] = "Hello";
for (int i = 0; msg[i]; i++) {
putchar(msg[i]);
}
putchar('\n');
return 0;
}
Example using getchar:
#include <stdio.h>
int main(void) {
int c;
printf("Type something: ");
while ((c = getchar()) != '\n' && c != EOF) {
putchar(c);
}
return 0;
}