K&R - Chapter 0 - Introduction using Python (Part 2)
Comparing Python and C Code
Printing Output in Python vs. C
print('Hello world')
print('Answer', 42)
print('Name', 'Sarah')
print('x', 3.5, 'i', 10)
# A comment
#include <stdio.h>
int main() {
printf("Hello world\n");
printf("Answer %d\n", 42);
printf("Name %s\n", "Sarah");
printf("x %.1f i %d\n", 3.5, 100);
}
/* A comment */
// Another comment
Output (for both Python and C)
Hello world
Answer 42
Name Sarah
x 3.5 i 100
#include <stdio.h>
: Read as “Pound include standard I O”
This tells the C compiler to include the standard input/output library, allowing the use of printf()
and other I/O functions.
Every C program must have a main()
function, where execution starts.int main()
specifies the return type as int
, indicating the program’s exit status (usually 0
for success).
printf("Hello world\n")
Prints text to the screen.\n
adds a newline, moving the cursor to the next line.
There cannot be single quotes used in a string, ''
means a single characters and ""
are character array (not a string).
In C, format codes (like %d
, %s
, %f
) are used inside the string to indicate where values should be inserted.%d
is used for integers, %s
for strings, and %.1f
for floating-point numbers with one decimal precision.
printf("Answer %d\n", 42);
The %d
is replaced with the integer 42
.
printf("x %.1f i %d\n", 3.5, 100);
%.1f
prints 3.5
with one decimal, and %d
prints 100
.
printf("Name %s\n", "Sarah");
%s
finds the string (character array) which will have to have a proper terminating \0
character at the end.
Number Input
print('Enter US Floor')
usf = int(input())
euf = usf - 1
print('EU Floor', euf)
#include <stdio.h>
int main() {
int usf, euf;
printf("Enter US Floor\n");
scanf("%d", &usf);
euf = usf - 1;
printf("EU Floor %d\n", euf);
}
Output
Enter US Floor
2
EU Floor 1
int usf, euf;
declares two integer variables, usf
and euf
.
scanf()
Function:
In C, scanf("%d", &usf)
works similarly to Python’s input()
.
The %d
format specifier tells scanf
to expect an integer.
The &
symbol means “pass the address of usf
” allowing scanf
to directly modify usf
by storing the input value in its memory location (this is called call by reference).
Without the &
, it would be call by value, and scanf
would not update the variable correctly.
Call by reference and call by value
In python int(input())
comes back as a function return so it is easy to assign it to usf
.
In C without &
on parameter it becomes call by value, where value of usf
is given to scanf
.&usf
says to give the value coming from the scanf
to the address of the usf
variable instead of the value of usf
, so the data can be stored.
So &
is the way C to call by reference for int and floats.
String Input
print('Enter name')
name = input()
print('Hello', name)
#include <stdio.h>
int main() {
char name[100];
printf("Enter name\n");
scanf("%100s", name);
printf("Hello %s\n", name);
}
Output
Enter name
Sarah
Hello Sarah
Declaring Character Arrays in C:
In C, char name[100];
defines an array to hold up to 100 characters (no strings in C, just arrays of characters).
This array has a fixed size and cannot dynamically grow like Python strings.
In Python, strings are objects and have dynamic sizes.
Using scanf
for String Input:scanf("%100s", name);
reads up to 100 characters into the name
array.%100s
format specifier limits the input to 100 characters.
In C, arrays are passed by reference, so there’s no need for &
with name
. Simply passing the array variable provides the address of the first element.
In C character array size has to be predefined, which can lead to buffer overflow issues if not managed carefully.
Reading a Full Line of Input
print('Enter line')
line = input()
print('Line:', line)
#include <stdio.h>
int main() {
char line[1000];
printf("Enter line\n");
scanf("%[^\n]1000s", line);
printf("Line: %s\n", line);
}
Output
Enter line
Hello world - have a nice day
Line: Hello world - have a nice day
Reading Until Newline:char line[1000]
Pre-defining a character array with space for 1000 characters.scanf("%[^\n]1000s", line);
reads all characters until a newline (\n
) is encountered.
The ^[\n]
format specifier is a regular expression that means “match any character except a newline.”
This allows to capture a full line of input (or up to 1000 characters).
Using fgets
for Reading Input
#include <stdio.h>
int main() {
char line[1000];
printf("Enter line\n");
fgets(line, 1000, stdin);
printf("Line: %s\n", line);
}
fgets()
for Safer Input:fgets(line, 1000, stdin);
reads up to 1000 characters from the standard input (stdin
) and stores them in the line
array.fgets
can read a file, the third parameter is a file handle, (there are 3 predefined file handles like stdin
)
Unlike scanf
, fgets
does not stop at whitespace, so it can read the entire line, including spaces.fgets
is generally safer than scanf
because it limits the number of characters to avoid buffer overflows.
C’s standard I/O library works with three standard file streams:
stdin
for inputstdout
for outputstderr
for error messages
Read a File
hand = open('romeo.txt')
for line in hand:
print(line.strip())
#include <stdio.h>
int main() {
char line[1000];
FILE *hand;
hand = fopen("romeo.txt", "r");
while( fgets(line, 1000, hand) != NULL ) {
printf("%s", line);
}
}
File Handling in C:FILE
is a type defined in stdio.h
.
FILE *hand;
declares a pointer to aFILE
object, which is used to handle file operations.fopen("romeo.txt", "r");
opens the file in read mode ("r"
).fgets(line, 1000, hand);
reads a line from the file into theline
array. It reads up to 1000 characters or until it encounters a newline.- The
while
loop continues untilfgets
returnsNULL
, which indicates the end of the file (EOF).
Key Differences:
- Python’s
open()
function is simpler and automatically handles file objects, while C requires you to manage the file pointer manually. - In C,
fgets()
is used to read lines, while Python uses a loop directly over the file object.
Counted Loop
for i in range(5):
print(i)
#include <stdio.h>
int main() {
int i;
for (i = 0; i < 5; i++) {
printf("%d\n", i);
}
}
Output:
0
1
2
3
4
C For Loop: The syntax in C is similar to Python but requires explicit initialization, condition, and increment.
for (i = 0; i < 5; i++)
initializesi
to 0, continues whilei
is less than 5, and incrementsi
by 1 on each iteration.
Python uses range(5)
to generate numbers, while C requires manual control over the loop variables.
Max / Min
maxval = None
minval = None
while True:
line = input()
line = line.strip()
if line == "done":
break
ival = int(line)
if (maxval is None or ival > maxval):
maxval = ival
if (minval is None or ival < minval):
minval = ival
print('Maximum', maxval)
print('Minimum', minval)
Input:
5, 2, 9, done
Output:
Maximum 9
Minimum 2
#include <stdio.h>
int main() {
int first = 1;
int val, maxval, minval;
while(scanf("%d", &val) != EOF) {
if (first || val > maxval) maxval = val;
if (first || val < minval) minval = val;
first = 0;
}
printf("Maximum %d\n", maxval);
printf("Minimum %d\n", minval);
}
Input:
5, 2, 9 (EOF)
Output:
Maximum 9
Minimum 2
In Python, maxval
and minval
are initially None
, and values are updated based on comparisons.
In C, the first
flag ensures that the maxval
and minval
are initialized on the first iteration.
scanf("%d", &val)
is used to read integers from the user, updating the val
variable.
Guessing Game
while True:
try:
line = input()
except: # if we get to EOF
break
line = line.strip()
guess = int(line)
if guess == 42:
print('Nice work')
elif guess < 42:
print('Too low - guess again')
else:
print('Too high - guess again')
#include <stdio.h>
int main() {
int guess;
while(scanf("%d", &guess) != EOF) {
if (guess == 42) {
printf("Nice work!\n");
break;
} else if (guess < 42) {
printf("Too low - guess again\n");
} else {
printf("Too high - guess again\n");
}
}
}
Python uses a try-except
block to handle EOF
or input errors, while C uses scanf
to read input and checks for EOF
.
In C, the code must use curly braces {}
for each block of statements within if
, else if
, and else
.
In python, if elif and else
is True multi-way if
.{}
is needed in C if there are more than one statement.
In C, if else if else
is not a true multi-way if
,
it checks the if
, when not true it will go to else
,
within the else
there are two more if else
nested inside so not part of a single block of code.
The indentation is done in a way that it looks like a multi-way if but it is not and the indentation doesn’t represent the nesting.
Functions (Call by Value)
def mymult(a, b):
c = a * b
return c
retval = mymult(6, 7)
print('Answer:', retval)
#include <stdio.h>
int main() {
int mymult(int, int); // function declaration
int retval;
retval = mymult(6, 7);
printf("Answer: %d\n", retval);
}
int mymult(int a, int b) { // function definition
int c = a * b;
return c;
}
Function Definition and Declaration in C:
int mymult(int, int);
declares the function signature, specifying it takes twoint
parameters and returns anint
.- The function body in C needs to explicitly declare types for the parameters, unlike Python where types are inferred.
C is statically typed, requiring explicit type declarations for variables and function parameters.