C slides
C slides
Lecture Slides
– Pocket calculator: not a computer ! Manipulates information, but is built to do a specific task (no changeable stored
program)
• This model is named the “von Neumann architecture” (John von Neumann – 1945; EDVAC - Electronic Discrete Variable
Automatic Computer – the first stored-program computer)
• Stored-program concept: earlier ideas in theoretical articles of: Alan Turing (1936), Konrad Zuse (1936)
Model of a computing machine
CPU
Input Device Output Device
ALU CU
DEFVAR a,b,c;
BEGIN
READ a
READ b
READ c
c := a+b
IF (c <10) THEN c:=c+10
PRINT c
END …
• High level languages
– Writing portable programs, using more abstract
instructions
– A high level instruction (statement) is translated into
many machine instructions
– Translation of high level language into machine
instructions: done by special computer programs –
compilers or interpreters
Compilers/Interpreters
Interpreter
main: a special name that indicates where the program must begin execution. It is
a special function.
first statement: calls a routine named printf, with argument the string of characters
“Programming is fun \n”
last statement: finishes execution of main and returns to the system a status value
of 0 (conventional value for OK)
The format in C
• Statements are terminated with semicolons
• Indentation is nice to be used for increased readability.
• Free format: white spaces and indentation is ignored by
compiler
• C is case sensitive – pay attention to lower and upper
case letters when typing !
– All C keywords and standard functions are lower case
– Typing INT, Int, etc instead of int is a compiler error
• Strings are placed in double quotes
• New line is represented by \n (Escape sequence)
Compiling and running C programs
Editor
Source code
file.c
Compiler
Object code
file.obj
Libraries Linker
Executable code
file.exe
IDE (Integrated
Development
Environment)
C Compilers and IDE’s
• One can:
– use a text editor to edit source code, and then use independent
command-line compilers and linkers
– use an IDE: everything together + facilities to debug, develop
and organize large projects
• There are several C compilers and IDE’s that support
various C compilers
• Lab: Dev-C++ IDE for C and C++, Free Software (under
the GNU General Public License)
– Works with gcc (GNU C Compiler)
• supports the C99 standard
• available on Windows and Unix
– The GNU Project (http://www.gnu.org/): launched in 1984 in
order to develop a complete Unix-like operating system which is
free software - the GNU system.
Debugging program errors
Syntactic Editor
Source code
Errors file.c
Compiler
Object code
file.obj
Libraries Linker
Executable code
file.exe
Semantic
Errors
Syntax and Semantics
• Syntax errors: violation of programming
language rules (grammar)
– "Me speak English good."
– Use valid C symbols in wrong places
– Detected by the compiler
• Semantics errors: errors in meaning:
– "This sentence is excellent Italian."
– Programs are syntactically correct but don’t produce
the expected output
– User observes output of running program
Second program
#include <stdio.h>
int main (void)
{
printf ("Programming is fun.\n");
printf ("And programming in C is even more fun.\n");
return 0;
}
Displaying multiple lines of text
#include <stdio.h>
int main (void)
{
printf ("Testing...\n..1\n...2\n....3\n");
return 0;
}
Output:
It is not necessary
to make a separate Testing...
call to printf for each ..1
line of output ! ...2
....3
Variables
• Programs can use symbolic names for
storing computation data and results
• Variable: a symbolic name for a memory
location
– programmer doesn’t has to worry about
specifying (or even knowing) the value of the
location’s address
• In C, variables have to be declared before
they are used
Using and Displaying Variables
#include <stdio.h>
int main (void)
{
int sum;
sum = 50 + 25;
printf ("The sum of 50 and 25 is %i\n", sum);
return 0;
}
The printf routine call has now 2 arguments: first argument a string containing also a
format specifier (%i), that holds place for an integer value to be inserted here
Displaying multiple values
#include <stdio.h>
int main (void)
{
int value1, value2, sum;
value1 = 50;
value2 = 25;
sum = value1 + value2;
printf ("The sum of %i and %i is %i\n",value1, value2, sum);
return 0;
}
#include <stdio.h>
int main (void)
{
// Declare variables
int value1, value2, sum;
// Assign values and calculate their sum
value1 = 50;
value2 = 25;
sum = value1 + value2;
// Display the result
printf ("The sum of %i and %i is %i\n",
value1, value2, sum);
return 0;
}
Computer Programming
Lecture 2
02.10.2012
Lecture 2: Outline
• Variables, Data Types, and Arithmetic Expressions [K- ch.4]
– Working with Variables
– Understanding Data Types and Constants
• The Basic Integer Type int
• The Floating Number Type float
• The Extended Precision Type double
• The Single Character Type char
• The Boolean Data Type _Bool
• Storage sizes and ranges
• Type Specifiers: long, long long, short, unsigned, and signed
– Working with Arithmetic Expressions
• Integer Arithmetic and the Unary Minus Operator
• The Modulus Operator
• Integer and Floating-Point Conversions
– Combining Operations with Assignment: The Assignment Operators
– Types _Complex and _Imaginary
Variables
• Programs can use symbolic names for storing
computation data
• Variable: a symbolic name for a memory location
– programmer doesn’t have to worry about specifying (or even
knowing) the value of the location’s address
• In C, variables have to be declared before they are used
– Variable declaration: [symbolic name(identifier), type]
• Declarations that reserve storage are called definitions
– The definition reserves memory space for the variable, but
doesn’t put any value there
• Values get into the memory location of the variable by
initialization or assignement
Variables - Examples
int a; // declaring a variable of type int
L-value R-value
int x =16;
printf("%i %#X %#o\n", x,x,x);
0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 storage (binary)
letter = ‘A'; /* OK */
letter = A; /* NO! Compiler thinks A is a variable */
letter = “A"; /* NO! Compiler thinks “A" is a string */
letter = 65; /* ok because characters are really
stored as numeric values (ASCII code),
but poor style */
Data display vs data storage
/* displays ASCII code for a character */
#include <stdio.h>
int main(void)
{
char ch;
ch='A';
printf("The code for %c is %i.\n", ch, ch);
return 0;
}
A 65 display
The Boolean Data Type _Bool
• A _Bool variable is defined in the language to be large enough to
store just the values 0 and 1.The precise amount of memory that is
used is unspecified.
• _Bool variables are used in programs that need to indicate a
Boolean condition. For example, a variable of this type might be
used to indicate whether all data has been read from a file.
• By convention, 0 is used to indicate a false value, and 1 indicates a
true value. When assigning a value to a _Bool variable, a value of
0 is stored as 0 inside the variable, whereas any nonzero value is
stored as 1.
• To make it easier to work with _Bool variables in your program, the
standard header file <stdbool.h> defines the values bool, true,
and false:
bool endOfData = false;
• The _Bool type has beed added by C99.
• Some compilers (Borland C, Turbo C, Visual C) don’t support it
Storage sizes and ranges
• Every type has a range of values associated with it.
• This range is determined by the amount of storage that is allocated
to store a value belonging to that type of data.
• In general, that amount of storage is not defined in the language. It
typically depends on the computer you’re running, and is, therefore,
called implementation- or machine-dependent.
– For example, an integer might take up 32 bits on your computer, or it
might be stored in 64.You should never write programs that make any
assumptions about the size of your data types !
• The language standards only guarantees that a minimum amount of
storage will be set aside for each basic data type.
– For example, it’s guaranteed that an integer value will be stored in a
minimum of 32 bits of storage, which is the size of a “word” on many
computers.
Integer overflow
• What happens if an integer tries to get a value too big for its type
(out of range)?
#include <stdio.h>
int main(void) {
int i = 2147483647;
printf("%i %i %i\n", i, i+1, i+2);
return 0;
}
Program output:
2147483647 -2147483648 -2147483647
Explanation:
On this computer, int is stored on 32 bits: the first bit represents
the sign, the rest of 31 bits represent the value.
Biggest positive int value here: 231-1 = 2147483647
Floating point round-off error
#include <stdio.h>
int main(void)
{
float a,b;
b = 2.0e20 + 1.0;
a = b - 2.0e20;
printf("%f \n", a);
return 0;
}
Program output:
4008175468544.000000
Explanation: the computer doesn't keep track of enough decimal places !
The number 2.0e20 is 2 followed by 20 zeros and by adding 1
you are trying to change the 21st digit. To do this correctly, the program
would need to be able to store a 21-digit number. A float number is typically
just six or seven digits scaled to bigger or smaller numbers with an
exponent.
Type Specifiers: long, long long,
short, unsigned, signed
• Type specifiers: extend or limit the range of certain basic types on
certain computer systems
• If the specifier long is placed directly before the int declaration, the
declared integer variable is of extended range on some computer
systems.
• Example of a long int declaration: long int factorial;
• On many systems, an int and a long int both have the same
range and either can be used to store integer values up to 32-bits
wide (231–1, or 2,147,483,647).
• A constant value of type long int is formed by optionally appending
the letter L (upper- or lowercase) at the end of an integer constant.
• Example: long int numberOfPoints = 131071100L;
• To display the value of a long int using printf, the letter l is used
as a modifier before the integer format characters i, o, and x
Basic Data Types - Summary
Type Meaning Constants Ex. printf
int Integer value; guaranteed to contain at least 16 bits 12, -7, %i,%d, %x,
0xFFE0, 0177 %o
short int Integer value of reduced precision; guaranteed to - %hi, %hx,
contain at least 16 bits %ho
long int Integer value of extended precision; guaranteed to 12L, 23l, %li, %lx,
contain at least 32 bits 0xffffL %lo
long long Integer value of extraextended precision; 12LL, 23ll, %lli,
int guaranteed to contain at least 64 bits 0xffffLL %llx, %llo
unsigned Positive integer value; can store positive values up 12u, 0XFFu %u, %x, %o
int to twice as large as an int; guaranteed to contain at
least 16 bits (all bits represent the value, no sign bit)
unsigned - %hu, %hx,
short int %ho
unsigned 12UL, 100ul, %lu, %lx,
long int 0xffeeUL %lo
• There are three imaginary types; An imaginary number has just an imaginary part:
• float _Imaginary represents the imaginary part with a type float value.
• double _Imaginary represents the imaginary part with a type double value.
• long double _Imaginary represents the imaginary part with a type long double
value.
• Complex numbers can be initialized using real numbers and the value I, defined in
<complex.h> and representing i, the square root of –1
_Complex example
Lecture 3
Lecture 3: Outline
• Program Looping [Kochan – chap.5]
– The for Statement
– Relational Operators
– Nested for Loops
– Increment Operator
– Program Input
– for Loop Variants
– The while Statement
– The do Statement
– The break Statement
– The continue Statement
Executing a program
• Program = list of
statements
– Entrypoint: the point where Statement1
the execution starts Statement2
Statement3
– Control flow: the order in Statement4
which the individual Statement5
statements are executed Statement6
Statement7
Statement8
Structure of a C program
Entry point of a C
program
#include <stdio.h>
int main (void)
{
int value1, value2, sum; Sequential
value1 = 50; flow of control
value2 = 25;
sum = value1 + value2;
printf ("The sum of %i and %i is %i\n",value1, value2, sum);
return 0;
}
Controlling the program flow
• Forms of controlling
the program flow:
– Executing a sequence Statement1
of statements Statement2
Statement3
– Repeating a sequence Statement4
of statements (until Statement5
some condition is met) Statement6
(looping) Statement7
Statement8
– Using a test to decide
between alternative
sequences (branching)
Program Looping
• Looping: doing one thing over and over
• Program loop: a set of statements that is executed
repetitively for a number of times
#include <stdio.h>
int main (void) {
int triangularNumber;
triangularNumber = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8;
printf ("The eighth triangular number is %i\n",
triangularNumber);
return 0;
}
init_expression n=1
no
loop_condition n<=200
yes
statement triangularNumber =
triangularNumber + n
loop_expression n=n+1
#include <stdio.h>
int main (void)
{
int n, triangularNumber;
triangularNumber = 0;
for ( n = 1; n <= 200; n = n + 1 )
triangularNumber = triangularNumber + n;
printf ("The 200th triangular number is %i\n",
triangularNumber);
return 0;
}
The for statement
for ( init_expression; loop_condition; loop_expression )
program statement
1 init_expression
no
5 2 loop_condition
yes
3 Program statement
4 Loop expression
The for statement
no
1 2 5 4
yes
for ( n = 1; n <= 200; n = n + 1 )
triangularNumber = triangularNumber + n;
3
How for works
• The execution of a for statement proceeds as follows:
1. The initial expression is evaluated first. This expression usually
sets a variable that will be used inside the loop, generally
referred to as an index variable, to some initial value.
2. The looping condition is evaluated. If the condition is not
satisfied (the expression is false – has value 0), the loop is
immediately terminated. Execution continues with the program
statement that immediately follows the loop.
3. The program statement that constitutes the body of the loop is
executed.
4. The looping expression is evaluated. This expression is
generally used to change the value of the index variable
5. Return to step 2.
Infinite loops
• It’s the task of the programmer to design correctly the algorithms so
that loops end at some moment !
The relational operators have lower precedence than all arithmetic operators:
a < b + c is evaluated as a < (b + c)
triangularNumber);
}
return 0;
} Remember indentations!
for loop variants
• Multiple expressions (comma between…)
for(i=0 , j=10 ; i<j ; i++ , j--)
• Omitting fields (semicolon have to be still…)
i=0;
for( ; i<10 ; i++ )
• Declaring variables
for(int i=0 ; i=10 ; i++ )
The while statement
while ( expression )
program statement
Loop_expression
no
yes
statement
Example:
• A program to find the greatest common divisor
of two nonnegative integer values …
Example - while
/* Program to find the greatest common divisor
of two nonnegative integer values */
#include <stdio.h>
int main (void)
{
int u, v, temp;
printf ("Please type in two nonnegative integers.\n");
scanf ("%i%i", &u, &v);
while ( v != 0 ) {
temp = u % v;
u = v;
v = temp;
}
printf ("Their greatest common divisor is %i\n", u);
return 0;
}
Example:
• A program to print out the digits of a number in
reverse order …
Example - while
// Program to reverse the digits of a number
#include <stdio.h>
int main (void)
{
int number, right_digit;
printf ("Enter your number.\n");
scanf ("%i", &number);
while ( number != 0 ) {
right_digit = number % 10;
printf ("%i", right_digit);
number = number / 10;
}
printf ("\n");
return 0;
}
Example – while not quite OK !
statement
yes
loop_expression
no
Example – do while
// Program to reverse the digits of a number
#include <stdio.h>
int main ()
{
int number, right_digit;
printf ("Enter your number.\n");
scanf ("%i", &number);
do {
right_digit = number % 10;
printf ("%i", right_digit);
number = number / 10;
}
while ( number != 0 );
printf ("\n");
return 0;
}
Which loop to choose ?
• Criteria: Who determines looping
– Entry-condition loop -> for, while
– Exit-condition loop -> do
• Criteria: Number of repetitions:
– Indefinite loops ->while
– Counting loops -> for
• In C, you can actually rewrite any while as
a for and viceversa !
Example: while vs for
Lecture 4
Lecture 4: Outline
• Making Decisions [chap 6 – Kochan]
– The if Statement
– The if-else Construct
– Logical Operators
– Boolean Variables
– Nested if Statements
– The else if Construct
– The switch Statement
– The Conditional Operator
• Character Input/Output
The if statement
if ( expression )
program statement
If expression is true
(non-zero), executes
statement.
If gives you the choice
no of executing statement
expression or skipping it.
yes
Program statement
Example - if
yes no
expression
if ( remainder == 0 )
printf ("The number is even.\n");
else
printf ("The number is odd.\n"); Syntactically OK
(void statement
on if) but
if ( x == 0 ); probably a
printf ("The number is zero.\n"); semantic error !
Example: compound relational test
// Program to determine if a year is a leap year
#include <stdio.h>
int main (void)
{
int year, rem_4, rem_100, rem_400;
printf ("Enter the year to be tested: ");
scanf ("%i", &year);
rem_4 = year % 4;
rem_100 = year % 100;
rem_400 = year % 400;
if ( (rem_4 == 0 && rem_100 != 0) || rem_400 == 0 )
printf ("It's a leap year.\n");
else
printf (“It's not a leap year.\n");
return 0;
}
Logical operators
Operator Symbol Meaning
Example: 5 || 0 is 1
Example
• Program to generate a table of all prime
numbers up to 50
Boolean variables
// Program to generate a table of prime numbers
#include <stdio.h>
int main (void) {
int p, d; A flag: assumes only
int isPrime; one of two different
values. The value of a
for ( p = 2; p <= 50; ++p ) {
flag is usually tested in
isPrime = 1; the program to see if it
for ( d = 2; d < p; ++d ) is “on” (TRUE) or “off ”
if ( p % d == 0 ) (FALSE)
isPrime = 0;
if ( isPrime != 0 )
printf ("%i ", p);
}
Equivalent test:
printf ("\n");
(more in C-style):
return 0;
if (isPrime)
}
Boolean variables
// Program to generate a table of prime numbers - rewritten
#include <stdio.h>
#include <stdbool.h>
int main (void) {
int p, d;
bool isPrime;
for ( p = 2; p <= 50; ++p ) {
isPrime = true;
for ( d = 2; d < p; ++d )
if ( p % d == 0 )
isPrime = false;
if ( isPrime )
printf ("%i ", p);
}
printf ("\n");
return 0;
}
Precedence of operators
Precedence
!, ++, --, (type)
*, /, %
+, -
<, <=, >, >=, ==, !=
&&
||
=
Because the order of evaluation for the <= operator is left-to-right, the
test expression is interpreted as follows:
(5<= x) <= 10
The subexpression 5 <= x either has the value 1 (for true) or 0 (for
false). Either value is less than 10, so the whole expression is always
true, regardless of x !
Testing for character ranges
char ch;
scanf(“%c”,&ch);
if (ch >= 'a' && ch <= 'z')
printf("lowercase char\n");
if (ch >= ‘A' && ch <= ‘Z')
printf(“uppercase char\n");
if (ch >= ‘0' && ch <= ‘9')
printf(“digit char\n");
• This works for character codes such as ASCII, in which the codes for
consecutive letters are consecutive numbers. However, this is not true for
some codes (i.e. EBCDIC)
• A more portable way of doing this test is to use functions from <ctype.h>
islower(ch), isupper(ch), isdigit(ch)
Other operations on characters
c will be the
char ch='d'; next letter ‘e’
ch=ch+1;
c will be the
char ch='d'; corresponding
ch=ch+'A'-'a'; uppercase letter
‘D’
• This works for character codes such as ASCII, in which the codes for
consecutive letters are consecutive numbers.
• A more portable way: <ctype.h> : toupper(c), tolower(c)
Nested if statements
if (number > 5)
if (number < 10)
printf(“1111\n");
else printf(“2222\n");
Rule: an else
goes with the most
recent if, unless
if (number > 5) { braces indicate
if (number < 10) otherwise
printf(“1111\n");
}
else printf(“2222\n");
Example: else-if
// Program to implement the sign function
#include <stdio.h>
int main (void)
{
int number, sign;
printf ("Please type in a number: ");
scanf ("%i", &number);
if ( number < 0 )
sign = -1;
else if ( number == 0 )
sign = 0;
else // Must be positive
sign = 1;
printf ("Sign = %i\n", sign);
return 0;
}
Multiple choices – else-if
int number;
if
negative if ( expression 1)
program statement 1
else else if ( expression 2)
program statement 2
else
if zero
program statement 3
else
positive
Program style: this
unindented formatting
improves the readability of
the statement and makes
it
clearer that a three-way
decision is being made.
Example: else-if
// Program to categorize a single character
// that is entered at the terminal
#include <stdio.h>
int main (void)
{
char c;
printf ("Enter a single character:\n");
scanf ("%c", &c);
if ( (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') )
printf ("It's an alphabetic character.\n");
else if ( c >= '0' && c <= '9' )
printf ("It's a digit.\n");
else
printf ("It's a special character.\n");
return 0;
}
Example – multiple choices
/* Program to evaluate simple expressions of the form
number operator number */
#include <stdio.h>
int main (void) {
float value1, value2;
char operator;
printf ("Type in your expression.\n");
scanf ("%f %c %f", &value1, &operator, &value2);
if ( operator == '+' )
printf ("%.2f\n", value1 + value2);
else if ( operator == '-' )
printf ("%.2f\n", value1 - value2);
else if ( operator == '*' )
printf ("%.2f\n", value1 * value2);
else if ( operator == '/' )
printf ("%.2f\n", value1 / value2);
else printf ("Unknown operator.\n");
return 0;
}
Example - switch
/* Program to evaluate simple expressions of the form
value operator value */
#include <stdio.h>
int main (void) {
float value1, value2;
char operator;
printf ("Type in your expression.\n");
scanf ("%f %c %f", &value1, &operator, &value2);
switch (operator) {
case '+': printf ("%.2f\n", value1 + value2); break;
case '-': printf ("%.2f\n", value1 - value2); break;
case '*': printf ("%.2f\n", value1 * value2); break;
case '/':
if ( value2 == 0 ) printf ("Division by zero.\n")
else printf ("%.2f\n", value1 / value2);
break;
default: printf ("Unknown operator.\n"); break;
}
return 0;
}
The switch statement
switch ( expression )
{
case value1:
program statement The expression is
program statement successively compared
... against the values value1,
break; value2, ..., valuen. If a case is
case value2: found whose value is equal to
program statement the value of expression, the
program statement
program statements that follow
...
break; the case are executed.
...
case valuen:
program statement The switch test expression must be
program statement
... one with an integer value (including
break; type char) (No float !).
default: The case values must be integer-
program statement type constants or integer constant
program statement
... expressions (You can't use a
break; variable for a case label !)
}
The switch statement (cont)
Break can miss !
Statement list on
a case can
miss !
switch (operator)
{
...
case '*':
case 'x':
printf ("%.2f\n", value1 * value2);
break;
...
}
The conditional operator
condition ? expression1 : expression2
maxValue = ( a > b ) ? a : b;
Equivalent to:
if ( a > b )
maxValue = a;
else
maxValue = b;
Standard input/output
• The C language itself does not have any special
statements for performing input/output (I/O)
operations; all I/O operations in C must be
carried out through function calls.
• These functions are contained in the standard C
library.
• #include <stdio.h>
• Formatted I/O: scanf(), printf()
• Character I/O: getchar(), putchar()
Brief overview - scanf()
• scanf(control string, list of arguments)
• Control string: contains format characters
– Important: match the number and type of format characters with the
number and type of following arguments !
– Format characters: as for printf
• Arguments: variable names prefixed with the address operator (&)
• Example:
• scanf(“%i %i”,&x,&y);
How scanf works
• Scanf: searches the input stream for a value to be read, bypasses
any leading whitespace characters
• scanf ("%f %f", &value1, &value2);
• scanf ("%f%f", &value1, &value2);
• In both cases, user can type:
3 <space> 5 <enter>
<space> 3 <space> <space> 5 <space> <enter>
3 <enter> 5 <enter>
• The exceptions: in the case of the %c format characters— the next
character from the input, no matter what it is, is read
• scanf ("%f %c %f", &value1, &op, &value2);
3 <space> + <space> 5 <enter>
3 <space> + <space> <space> <enter> 5 <enter>
• scanf ("%f%c%f", &value1, &op, &value2);
3+5<enter>
Not OK: 3 <space> +5<enter> => op would take the value <space>,
character + would remain as input for value2 !
How scanf works
• When scanf reads in a particular value: reading of the value
terminates when a character that is not valid for the value type being
read is encountered.
• scanf ("%f%c%f", &value1, &op, &value2);
3+5<enter>
• Any nonformat characters that are specified in the format string of
the scanf call are expected on the input.
• scanf ("%i:%i:%i", &hour, &minutes, &seconds);
3:6:21<enter>
3<space>:<space>6<space>:<space>21<enter>
3<space>6<space>21<space> => NOT OK !
• The next call to scanf picks up where the last one left off.
• scanf ("%f", &value1);
• User types: 7 <space> 8 <space> 9 <enter>
• 7 is stored in value1, rest of the input chars remain waiting in buffer
• scanf ("%f", &value2);
• 8 from buffer is stored in value2, rest of the input remains waiting
getchar() and putchar()
• The simplest input mechanism is to read one
character at a time from the standard input,
with getchar
• To display a character: putchar
Example: getchar()
#include <stdio.h>
int main(void) { Buffered input: the
char ch; characters you type are
while ((ch = getchar()) != '#') collected and stored in a
putchar(ch); buffer. Pressing Enter
return 0; causes the block of
} characters you typed to
be made available to
your program
Hello ! I am<enter>
Hello ! I am
Joe from #3.<enter>
Joe from
Terminating keyboard input
Which character as
sign of end of input ?
#include <stdio.h> You need a
int main(void) { terminating character
int ch; that normally does
while ((ch = getchar()) != EOF) not show up in text.
putchar(ch);
return 0;
}
#include <stdio.h>
int main(void) {
int c, nl, nc;
nl = 0;
nc = 0;
while ((c = getchar()) != EOF) {
nc++;
if (c == '\n')
nl++;
}
printf("Number of lines in input: %d\n", nl);
printf("Number of characters in input: %d\n", nc);
return 1;
}
Computer programming
Lecture 5
Lecture 5: Outline
• Arrays [chap 7 – Kochan]
– The concept of array
– Defining arrays
– Initializing arrays
– Character arrays
– Multidimensional arrays
– Variable length arrays
The concept of array
• Array: a set of ordered data items
• You can define a variable called x, which represents not a single
value, but an entire set of values.
• Each element of the set can then be referenced by means of a
number called an index number or subscript.
• Mathematics: a subscripted variable, xi, refers to the ith element x in
a set
• C programming: the equivalent notation is x[i]
Declaring an array
• Declaring an array variable:
– Declaring the type of elements that will be contained in the array—
such as int, float, char, etc.
– Declaring the maximum number of elements that will be stored inside
the array.
• The C compiler needs this information to determine how much memory
space to reserve for the array.)
• This must be a constant integer value
• The range for valid index values in C:
– First element is at index 0
– Last element is at index [size-1]
– It is the task of the programmer to make sure that array elements are
referred by indexes that are in the valid range ! The compiler cannot
verify this, and it comes to severe runtime errors !
Arrays - Example
Example:
int values[10];
Declares an array of 10 elements of type int
Using Symbolic Constants for array size:
#define N 10
…
int values[N];
Valid indexes:
values[0]=5;
values[9]=7;
Invalid indexes:
values[10]=3;
values[-1]=6;
In memory: elements of an array are stored
at consecutive locations
Arrays - Example
#include <stdio.h> Using symbolic
#define N 6 constants for array
int main (void) size makes program
{ more general
int values[N];
int index;
for ( index = 0; index < N; ++index ) {
printf(“Enter value of element #%i \n”,index);
scanf(“%i”, &values[index]);
}
for ( index = 0; index < N; ++index )
printf ("values[%i] = %i\n", index, values[index]);
return 0;
}
Typical loop for
processing all
elements of an array
What goes wrong if an index goes
out of range ?
#include <stdio.h>
#define NA 4
#define NB 7
int main (void) {
int b[NB],a[NA];
int index;
for ( index = 0; index < NB; ++index )
b[index]=10+index;
for ( index = 0; index < NA+2; ++index )
a[index]=index;
response
ratingCounters
++
0 1 2 9 10
2 3 5 7 11
0 1 2
primeIndex
Exercise: Prime numbers
#include <stdio.h>
#include <stdbool.h>
// Modified program to generate prime numbers
int main (void) {
int p, i, primes[50], primeIndex = 2;
bool isPrime;
primes[0] = 2;
primes[1] = 3;
for ( p = 5; p <= 50; p = p + 2 ) {
isPrime = true;
for ( i = 1; isPrime && p / primes[i] >= primes[i]; ++i )
if ( p % primes[i] == 0 )
isPrime = false;
if ( isPrime == true ) {
primes[primeIndex] = p;
++primeIndex;
}
}
for ( i = 0; i < primeIndex; ++i )
printf ("%i ", primes[i]);
printf ("\n");
return 0;
}
Initializing arrays
• int counters[5] = { 0, 0, 0, 0, 0 };
• char letters[5] = { 'a', 'b', 'c', 'd', 'e' };
• float sample_data[500] = { 100.0, 300.0, 500.5 };
• The C language allows you to define an array without specifying the
number of elements. If this is done, the size of the array is
determined automatically based on the number of initialization
elements: int counters[] = { 0, 0, 0, 0, 0 };
Character arrays
#include <stdio.h>
int main (void)
{
char word[] = { 'H', 'e', 'l', 'l', 'o', '!' };
int i;
for ( i = 0; i < 6; ++i )
printf ("%c", word[i]);
printf ("\n");
return 0;
}
a special case of character arrays: the character string type =>in a later chapter
Example: conversion to base b
• Convert a number from base 10 into a base b, b in range [2..16]
convertedNumber[index] = numberToConvert
% base;
++index;
numberToConvert =
numberToConvert / base;
}
while ( numberToConvert != 0 );
// display the results in reverse order
printf ("Converted number = ");
for (--index; index >= 0; --index ) {
nextDigit = convertedNumber[index];
printf ("%c",
baseDigits[nextDigit]);
}
printf ("\n");
Multidimensional arrays
• C language allows arrays of any number of dimensions
• Two-dimensional array: matrix
int M[4][5] = {
{ 10, 5, -3, 17, 82 },
{ 9, 0, 0, 8, -7 },
{ 32, 20, 1, 0, 14 },
{ 0, 0, 8, 7, 6 }
};
int M[4][5] = { 10, 5, -3, 17, 82, 9, 0, 0, 8, -7, 32,20,
1, 0, 14, 0, 0, 8, 7, 6 };
Example: Typical matrix processing
#define N 3
#define M 4
int main(void) {
int a[N][M];
int i,j;
/* read matrix elements */
for(i = 0; i < N; i++)
for(j = 0; j< M; j++) {
printf("a[%d][%d] = ", i, j);
scanf("%d", &a[i][j]);
}
/* print matrix elements */
for(i = 0; i < N; i++) {
for(j = 0; j< M; j++)
printf("%5d", a[i][j]);
printf("\n");
}
return 0;
}
Example: Dealing with variable
numbers of elements
#include <stdio.h>
#define NMAX 4
int main(void) {
int a[NMAX];
int n;
int i;
printf("How many elements(maximum %d)?\n",NMAX);
scanf("%d",&n);
if (n>NMAX) {
printf(“Number too big !\n”);
return 1;
}
for(i = 0; i < n; i++)
scanf("%d", &a[i]);
for(i = 0; i < n; i++)
printf("%5d", a[i]);
printf("\n");
return 0;
}
Variable length arrays
• A feature introduced by C99
• It was NOT possible in ANSI C !
• int a[n];
• The array a is declared to contain n elements. This is called a
variable length array because the size of the array is specified by a
variable and not by a constant expression.
• The value of the variable must be known at runtime when the array
is created => the array variable will be declared later in the block of
the program
• Possible in C99: variables can be declared anywhere in a program,
as long as the declaration occurs before the variable is first used.
• A similar effect of variable length array could be obtained in ANSI C
using dynamic memory allocation to allocate space for arrays while
a program is executing.
Example: Variable length arrays
#include <stdio.h>
int main(void) {
int n;
int i;
int main(void) {
int n; Array a
int i; created of size
7
n=7;
int a[n];
for(i = 0; i < n; i++)
a[i]=i Variable-length array
n=20; does NOT mean that
Wrong! for(i = 0; i < n; i++) you can modify the
a[i]=2*i; length of the array
printf("\n"); after you create it !
return 0; Once created, a VLA
} keeps the same size !
Computer programming
Lectures 6&7
Lectures 6&7: Outline
• Functions [chap 8 – Kochan]
– Defining a Function
– Arguments and Local Variables
• Automatic Local Variables
– Returning Function Results
– Declaring a Function Prototype
– Functions and Arrays
• Arrays as parameters
• Sorting Arrays
• Multidimensional Arrays
– Global Variables
– Automatic and Static Variables
– Recursive Functions
What is a function
• A function in C: is a self-contained unit of program code designed to
accomplish a particular task.
• The concept has some equivalent in all high-level programming
languages: functions, subroutines, and procedures
• The use of a function: a "black box"
– defined in terms of the information that goes in (its input) and the value
or action it produces (its output).
– what goes on inside the black box is not your concern, unless you are
the one who has to write the function.
– Think on how you used functions printf, scanf, getchar !
• What kind of “output” comes out from a function black box ?
– Some functions find a value for a program to use. Example: getchar()
returns to the program the next character from the standard input buffer.
– Some functions cause an action to take place. Example: printf() causes
data to be printed on the screen
– In general, a function can both produce actions and provide values.
Defining a function
#include <stdio.h>
main printf
printMesage
{ { {
} }
return-type arguments
void printMessage ( void )
{
printf ("Programming is fun.\n");
}
Function prototype
• The first line of the function definition
• Contains everything that others (other functions) need to
know about the function in order to use it (call it)
Function prototype
{ {
10 n
20 i
50 triangularNb
Example: scope of local variables
#include <stdio.h>
void f1 (float x) {
int n=6;
printf(“%f \n”, x+n);
}
int f2(void) {
float n=10;
printf(“%f \n”,n);
}
int main (void)
{
int n=5;
f1(3);
f2();
return 0;
}
Arguments are passed by copying
values !
• In a function call, the actual argument is
evaluated, and its value is copied to the
corresponding formal parameter for the
function.
– Because the called function works with data
copied from the calling function, the original
data in the calling function is protected from
whatever manipulations the called function
applies to the copies
Example: arguments
#include <stdio.h>
void gcd (int u, int v)
{
int temp;
printf ("The gcd of %i and %i is ", u, v);
while ( v != 0 ) {
temp = u % v;
u = v;
v = temp;
}
printf ("%i\n", u);
}
int main (void)
{
gcd (150, 35);
gcd (1026, 405);
gcd (83, 240);
return 0;
Example: arguments are passed by
copying values !
#include <stdio.h>
void gcd (int u, int v)
{
int temp;
printf ("The gcd of %i and %i is ", u, v);
while ( v != 0 ) { The formal
temp = u % v; parameters u and v
u = v; are assigned new
v = temp; values in the
} function
printf ("%i\n", u);
}
The actual
int main (void)
parameters x and y
{
are not changed !
int x=10,y=15;
gcd (x, y);
printf(“x=%i y=%i \n”,x,y);
return 0;
Example: arguments are passed by
copying values !
#include <stdio.h>
void multiplyBy2 (float x)
{
printf(“parameter at start: %.2f, at %p \n”,x,
&x);
x*=2;
printf(“parameter at end: %.2f, at %p \n”,x, &x);
}
int main (void)
{
float y = 7;
printf (“y before call: %.2f, at %p \n", y, &y);
multiplyBy2 (y);
printf (“y after call: %.2f, at %p \n", y, &y);
return 0;
}
Arguments by copying
main multiplyBy2
{ {
y 7 x
714
Returning function results
• A function in C can optionally return a single value
• return expression;
• The value of expression is returned to the calling function. If the type of
expression does not agree with the return type declared in the function
declaration, its value is automatically converted to the declared type before it
is returned.
• A simpler format for declaring the return statement is as follows:
• return;
• Execution of the simple return statement causes program execution to be
immediately returned to the calling function.This format can only be used to
return from a function that does not return a value.
• If execution proceeds to the end of a function and a return statement is not
encountered, it returns as if a return statement of this form had been
executed. Therefore, in such a case, no value is returned.
• If the declaration of the type returned by a function is omitted, the C compiler
assumes that the function returns an int !
Return example
#include <limits.h>
int minValue, i;
minValue = INT_MIN;
for ( i = 0; i < 10; ++i )
if ( values[i] < minValue )
minValue = values[i];
Example: Passing arrays as
parameters
// Function to find the minimum value in an array
#include <stdio.h>
int minimum (int values[], int n) {
int minValue, i;
minValue = values[0];
for ( i = 1; i < n; ++i )
if ( values[i] < minValue )
minValue = values[i];
return minValue;
}
int main (void) {
int scores[10], i, minScore;
printf ("Enter 10 scores\n");
for ( i = 0; i < 10; ++i )
scanf ("%i", &scores[i]);
minScore = minimum (scores);
printf ("\nMinimum score is %i\n", minScore);
return 0;
}
Example: No size specified for
formal parameter array
// Function to find the minimum value in an array
#include <stdio.h>
int minimum (int values[], int numberOfElements)
{
int minValue, i;
minValue = values[0];
for ( i = 1; i < numberOfElements; ++i )
if ( values[i] < minValue )
minValue = values[i];
return minValue;
}
int main (void)
{
int array1[5] = { 157, -28, -37, 26, 10 };
int array2[7] = { 12, 45, 1, 10, 5, 3, 22 };
printf ("array1 minimum: %i\n", minimum (array1, 5));
printf ("array2 minimum: %i\n", minimum (array2, 7));
return 0;
}
Array parameters are passed by
reference !
• Parameters of non-array type: passed by copying values
• Parameters of array type: passed by reference
– the entire contents of the array is not copied into the formal
parameter array.
– the function gets passed information describing where in the
computer’s memory the original array is located.
– Any changes made to the formal parameter array by the function
are actually made to the original array passed to the function,
and not to a copy of the array.
– This change remains in effect even after the function has
completed execution and has returned to the calling routine.
Example: Array parameters are
passed by reference !
#include <stdio.h>
void multiplyBy2 (float array[], int n)
{
int i;
for ( i = 0; i < n; ++i )
array[i] *= 2;
}
int main (void)
{
float floatVals[4] = { 1.2f, -3.7f, 6.2f, 8.55f };
int i;
multiplyBy2 (floatVals, 4);
for ( i = 0; i < 4; ++i )
printf ("%.2f ", floatVals[i]);
printf ("\n");
return 0;
}
Sorting arrays
// Program to sort an array of integers
// into ascending order
#include <stdio.h>
void sort (int a[], int n)
{
int i, j, temp;
for ( i = 0; i < n - 1; ++i )
for ( j = i + 1; j < n; ++j )
if ( a[i] > a[j] ) {
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
Sorting arrays - continued
void sort (int a[], int n);
• Valid examples:
function(int array_values[100][50]);
function(int array_values[][50]);
• Invalid examples:
function(int array_values[100][]);
function(int array_values[][]);
Example: multidimensional array as
function parameter
The number of
columns must be specified !
No generic matrix display function possible !
int x;
void f1 (void) {
x++;
}
void f2 (void) {
x++;
}
int main(void) {
x=7;
f1();
f2();
printf(“x=%i \n”,x);
}
Automatic and static variables
• Automatic local variables (the default case of local vars) :
– an automatic variable disappears after the function where it is defined
completes execution, the value of that variable disappears along with it.
– the value an automatic variable has when a function finishes execution is
guaranteed not to exist the next time the function is called.
– The value of the expression is calculated and assigned to the automatic local
variable each time the function is called.
• Static local variables:
– If you place the word static in front of a variable declaration
– “something that has no movement”
– a static local variable—it does not come and go as the function is called and
returns. This implies that the value a static variable has upon leaving a
function is the same value that variable will have the next time the function is
called.
– Static variables also differ with respect to their initialization. A static, local
variable is initialized only once at the start of overall program execution—and
not each time that the function is called. Furthermore, the initial value
specified for a static variable must be a simple constant or constant
expression. Static variables also have default initial values of zero, unlike
automatic variables, which have no default initial value.
Example: Automatic and static
variables
// Program to illustrate static and automatic variables
#include <stdio.h>
void auto_static (void)
{
int autoVar = 1;
static int staticVar = 1;
printf ("automatic = %i, static = %i\n", autoVar, staticVar);
++autoVar;
++staticVar;
}
int main (void)
{
int i;
for ( i = 0; i < 5; ++i )
auto_static ();
return 0;
}
Recursive functions
• C permits a function to call itself. This process is named
recursion.
• Useful when the solution to a problem can be expressed in terms of
successively applying the same solution to subsets of the problem
• Example: factorial: recursive definition:
• n! = n * (n-1)!
factorial(n) factorial(n-1)
Example: recursive function
// Recursive function to calculate the factorial of n
unsigned long int factorial (unsigned int n)
{
unsigned long int result;
if ( n == 0 )
result = 1;
else
result = n * factorial (n - 1);
return result;
}
factorial(3)=3 * factorial(2); =6
factorial(2) = 2 * factorial(1); =2
factorial(1)= 1 * factorial(0); =1
factorial(0)= 1
Recursive function calls
• Each time any function is called in C—be it
recursive or not—the function gets its own
set of local variables and formal
n: 0
parameters with which to work !
• These local automatic variables are stored result: 1
in a memory area called stack
• Each new function call pushes a new
activation record on the stack n: 1
• This activation record contains its set of result: 1
automatic local variables
• When a function call returns, its activation
record is removed from the top of the stack n: 2
void up_and_down(int n)
{
printf(“Start call %d: n location %p\n", n, &n);
if (n < 4)
up_and_down(n+1);
printf(“End call %d: n location %p\n", n, &n);
}
...
up_and_down(0);
Recursion pros and cons
• Tricky with recursion: programmer must make sure to get the
recursion to an end at some time !
– a function that calls itself tends to do so indefinitely unless the
programming includes a conditional test to terminate recursion.
• Recursion often can be used where loops can be used. Sometimes
the iterative solution is more obvious; sometimes the recursive
solution is more obvious.
• Recursive solutions tend to be more elegant and less efficient
than iterative solutions.
Functions - Summary
• We distinguish between Function definition, function declaration and
Function call
Global variable
Automatic local
variable
Static local
variable
Lecture 8
Lecture 8: Outline
• Structures [Kochan, chap 9]
– Defining and using Structures
– Functions and Structures
– Initializing Structures. Compound Literals
– Arrays of Structures
– Structures Containing Structures and/or Arrays
• More on Data Types [Kochan, chap 14]
– Enumerated Data Types
– The typedef Statement
– Data Type Conversions
The concept of structures
• Structure: a tool for grouping heterogenous elements together.
• Array: a tool for grouping homogenous elements together
• Example: storing calendar dates (day, month, year)
• Version1: using independent variables:
• int month = 9, day = 25, year = 2004;
• Using this method, you must keep track of three separate variables
for each date that you use in the program—variables that are
logically related. It would be much better if you could somehow
group these sets of three variables together. This is what the
structure in C allows you to do !
Example: structures
struct date Defines type struct date, with 3 fields of type int
{ The names of the fields are local in the context
int month; of the structure.
int day; A struct declaration defines a type: if not followed by a
int year; list of variables it reserves no storage; it merely
}; describes a template or shape of a structure.
if ( today.day != daysPerMonth[today.month - 1] ) {
tomorrow.day = today.day + 1;
tomorrow.month = today.month;
tomorrow.year = today.year;
}
else if ( today.month == 12 ) { // end of year
tomorrow.day = 1;
tomorrow.month = 1;
tomorrow.year = today.year + 1;
}
else { // end of month
tomorrow.day = 1;
tomorrow.month = today.month + 1;
tomorrow.year = today.year;
}
printf ("Tomorrow's date is %i/%i/%i.\n", tomorrow.month,
tomorrow.day, tomorrow.year );
return 0;
}
Operations on structures
• Legal operations on a structure are :
– copying it or assigning to it as a unit
• this includes passing arguments to functions and returning values
from functions as well.
– taking its address with &
– accessing its members.
– structures may not be compared as units !
– a structure may be initialized by a list of constant member values
Example: determine tomorrow’s
date (Version 2)
// Program to determine tomorrow's date
#include <stdio.h>
#include <stdbool.h>
&thisDay.year);
nextDay = dateUpdate (thisDay);
printf ("Tomorrow's date is %i/%i/%i.\n",nextDay.month,
nextDay.day, nextDay.year );
return 0;
Example continued
int numberOfDays (struct date d);
. . .
event.sdate.month = 10;
Structures containing arrays
struct month
{
int numberOfDays;
char name[3];
};
. . .
aMonth.numberOfDays = 31;
aMonth.name[0] = 'J';
aMonth.name[1] = 'a';
aMonth.name[2] = 'n';
Enumerated data type
• You can use the enumerated type to declare symbolic names to represent
integer constants.
• By using the enum keyword, you can create a new "type" and specify the
values it may have.
• Actually, enum constants are type int; therefore, they can be used wherever
you would use an int.
• The purpose of enumerated types is to enhance the readability of a
program.
• enum primaryColor { red, yellow, blue };
• enum primaryColor myColor, gregsColor;
• myColor = red;
• if ( gregsColor == yellow ) …
Enumerated data type
• The C compiler actually treats enumeration identifiers as integer constants.
Beginning with the first name in the list, the compiler assigns sequential
integer values to these names, starting with 0.
• enum month thisMonth;
• ...
• thisMonth = february;
• the value 1 is assigned to thisMonth because it is the second identifier
listed inside the enumeration list.
• If you want to have a specific integer value associated with an enumeration
identifier, the integer can be assigned to the identifier when the data type is
defined. Enumeration identifiers that subsequently appear in the list are
assigned sequential integer values beginning with the specified integer
value plus 1. For example, in the definition
• enum direction { up, down, left = 10, right };
• an enumerated data type direction is defined with the values up, down, left,
and right. The compiler assigns the value 0 to up because it appears first in
the list; 1 to down because it appears next; 10 to left because it is explicitly
assigned this value; and 11 to right because it appears immediately after left
in the list.
Example: enum
// Program to print the number of days in a month
#include <stdio.h>
int main (void)
{
enum month { january = 1, february, march, april, may,
june,july, august, september, october, november, december
};
enum month aMonth;
int days;
printf (“Enter month number: “);
scanf (“%i”, &aMonth);
Cont.
switch (aMonth ) {
case january: case march: case may: case
july:
case august: case october: case december:
days = 31; break;
case april: case june: case september: case
november:
days = 30; break;
case february:
days = 28; break;
default:
printf (“bad month number\
n”);
days = 0; break;
}
if ( days != 0 )
printf (“Number of days is %i\n”, days);
if ( amonth == february )
printf (“...or 29 if it’s a leap year\n”);
return 0;
}
The typedef statement
• C provides a capability that enables you to assign an alternate name to
a data type. This is done with a statement known as typedef.
• The statement
typedef int Counter;
• defines the name Counter to be equivalent to the C data type int.
Variables can subsequently be declared to be of type Counter, as in the
following statement:
Counter j, n;
• The C compiler actually treats the declaration of the variables j and n,
shown in the preceding code, as normal integer variables.
• The main advantage of the use of the typedef in this case is in the
added readability that it lends to the definition of the variables.
• the typedef statement does not actually define a new type—only a
new type name.
The typedef statement
• In forming a typedef definition, proceed as though a normal variable
declaration were being made. Then, place the new type name where the
variable name would normally appear. Finally, in front of everything, place the
keyword typedef:
• typedef char Linebuf [81];
• defines a type called Linebuf, which is an array of 81 characters. Subsequently
declaring variables to be of type Linebuf, as in
• Linebuf text, inputLine;
typedef struct
{
int month;
int day;
int year;
} Date;
Date birthdays[100];
Data type conversions
• Expressions: Operands and operators
• Operands may be of different types; issue: how is the expression
evaluated and what is the type of the result ?
• Example: the case examined in lecture 2 was with the data types float
and int: an operation that involved a float and an int was carried out as a
floating-point operation, the integer data item being automatically
converted to floating point.
• N=8
• W= 11111011
• W=(-1)*27+1*26+1*25+1*24+1*23+0+1*21+1*20 =-5
Two’s complement example
• A convenient way to convert a negative number from
decimal to binary:
1. add 1 to the value
2. express the absolute value of the result in binary
3. and then “complement” all the bits; that is, change all 1s to 0s
and 0s to 1s.
• Example: convert -5 to binary:
1. First 1 is added, which gives -4;
2. Value 4 expressed in binary is 00000100
3. Complementing the bits produces 11111011.
Signed & Unsigned types
• If in an expression appear both signed and unsigned operands, signed
operands are automatically converted to unsigned
• Converting signed to unsigned:
– No change in bit representation
– Nonnegative values unchanged
– Negative values change into positive values !
– Example: int x=-5; unsigned int ux=(unsigned int) x;
printf(“%ud \n”,ux); // 4294966*62
• Conversion surprises:
int a=-5;
unsigned int b=1;
2. "x" really consists of two characters, 'x' and '\0', the null character
Escape characters
\a Audible alert • the backslash character has a
\b Backspace special significance
\f Form feed
\n Newline
• other characters can be combined
\r Carriage return with the backslash character to
\t Horizontal tab perform special functions. These
\v Vertical tab are referred to as escape
\\ Backslash characters.
\" Double quotation mark
\' Single quotation mark
\? Question mark
\nnn Octal character value nnn
\unnnn Universal character name
\Unnnnnnnn Universal character
name
\xnn Hexadecimal character value
nn
Examples: Escape characters
c = '\'';
printf("\033\"Hello\"\n");
Displaying character strings
• Displaying a string: %s
• printf ("%s\n", word);
Inputting character strings
• char string[81];
• scanf ("%s", string); // NOT recommended !
– The scanf function can be used with the %s format characters to read in a
string of characters up to a blank space, tab character, or the end of the line,
whichever occurs first
– The string terminator (null character) is appended to string
– Note that unlike previous scanf calls, in the case of reading strings, the & is
not placed before the array name !
– If you type in more than 80 consecutive characters to the preceding program
without pressing the spacebar, the tab key, or the Enter (or Return) key,
scanf overflows the character array !
• Correct use of scanf for reading strings:
• scanf ("%80s", string); // Safer version !
– If you place a number after the % in the scanf format string, this tells scanf
the maximum number of characters to read.
Example: string processing
#include <stdio.h>
• #include <string.h>
• strcat (s1, s2)
– Concatenates the character string s2 to the end of s1, placing a null
character at the end of the final string.The function also returns s1.
• strcmp (s1, s2)
– Compares strings s1 and s2 and returns a value less than zero if s1 is
less than s2, equal to zero if s1 is equal to s2, and greater than zero if s1
is greater than s2.
• strcpy (s1, s2)
– Copies the string s2 to s1, also returning s1.
• strlen (s)
– Returns the number of characters in s, excluding the null character.
String functions (cont.)
• strncat (s1, s2, n)
– Copies s2 to the end of s1 until either the null character is reached or n
characters have been copied, whichever occurs first. Returns s1.
• strncmp (s1, s2, n)
– Performs the same function as strcmp, except that at most n characters
from the strings are compared.
• strncpy (s1, s2, n)
– Copies s2 to s1 until either the null character is reached or n characters
have been copied, whichever occurs first. Returns s1.
• strchr (s, c)
– Searches the string s for the last occurrence of the character c. If found,
a pointer to the character in s is returned; otherwise, the null pointer is
returned.
• strstr (s1, s2)
– Searches the string s1 for the first occurrence of the string s2. If found,
a pointer to the start of where s2 is located inside s1 is returned;
otherwise, if s2 is not located inside s1, the null pointer is returned.
Example: String functions
#include <stdio.h>
int main(void) {
char name[40];
printf("What's your name?\n");
scanf("%39s", name);
printf("Hello, %s. %s\n", name, PRAISE);
printf("Your name of %d letters occupies %d memory \n",
strlen(name), sizeof name);
return 0;
}
Example: String functions
#include <stdio.h>
#include <string.h>
int main(void) {
char string1[] = "this is";
char string2[] = "a test";
char string3[20] = "Hello, ";
char string4[] = "world!";
printf("%s\n", string3);
strcat(string3, string4);
printf("%s\n", string3);
if(strcmp(string1, string2) == 0)
printf("strings are equal\n");
else printf("strings are different\n");
return 0;
}
String to number conversions
• Storing a number as a string means storing the digit characters
• Example: the number 213 can be stored in a character string array
as the digits '2', '1', '3', '\0'. Storing 213 in numeric form means
storing it as an int.
• C requires numeric forms for numeric operations, such as addition
and comparison, but displaying numbers on your screen requires a
string form because a screen displays characters. The printf() and
scanf() functions, through their %d and other specifiers, convert
numeric forms to string forms, and vice versa.
• C also has functions whose sole purpose is to convert string forms
to numeric forms.
String to number
conversion functions
• <stdlib.h>
• atoi(s) converts string s to a type int value and returns it. The function
converts characters until it encounters something that is not part of an
integer.
• atof() converts a string to a type double value and returns it
• atol() converts a string to a type long value and returns it
// Using atoi
#include <stdio.h>
#include <stdlib.h>
int main (void) {
printf ("%i\n", atoi("245"));
printf ("%i\n", atoi("100") + 25);
printf ("%i\n", atoi("13x5"));
return 0;
}
String to number conversion
Do-it-yourself exercise
// Function to convert a string to an integer – my atoi
#include <stdio.h>
int strToInt (const char string[]) {
int i, intValue, result = 0;
for ( i = 0; string[i] >= '0' && string[i] <= '9'; ++i )
{
intValue = string[i] - '0';
result = result * 10 + intValue;
}
return result;
}
int main (void) {
printf ("%i\n", strToInt("245"));
printf ("%i\n", strToInt("100") + 25);
printf ("%i\n", strToInt("13x5"));
return 0;
}
Example: readLine
#include <stdio.h>
#include <stdio.h>
int a[10];
int *pa;
pa=&a[0];
Or
pa=a;
pa=a; a=pa;
pa++; a++;
T tab[N];
T * p;
p=tab;
p=p+n; // p contains the address of tab[n].
Pointer arithmetic
• Comparison of two pointers.
• If p and q point to members of the same array, then relations like ==, !=,
<, >=, etc., work properly.
– For example, p < q is true if p points to an earlier element of the array than q
does.
• Any pointer can be meaningfully compared for equality or inequality with
zero.
• Pointer subtraction :
• if p and q point to elements of the same array, and p<q, then q-p+1 is
the number of elements from p to q inclusive.
char *p=“hello” ;
printf(“%c”,*++p); // displays
e
Example: Character pointers and
functions
/* strcpy: copy t to s; array subscript version */
void strcpy(char s[], char t[])
{
int i;
i = 0;
while ((s[i] = t[i]) != '\0')
i++;
}
…
int a[3]={1,2,3};
BIG MISTAKE !
int b[3]={4,5,6}; The function
int * rr; returns the
rr=add_vector3(a,b,3); address of a
print_vector(rr,3); local variable !
Exercise: different versions of
adding 2 vectors
int * add_vector3(int *a, int *b, int n) {
static int r[3];
int i;
for (i=0; i<n; i++, a++, b++)
r[i]=*a+*b;
return r; Does this solve
} the problem ?
…
int a[3]={1,2,3};
int b[3]={4,5,6};
int * rr;
rr=add_vector3(a,b,3);
print_vector(rr,3);
Exercise: different versions of
adding 2 vectors
int * add_vector3(int *a, int *b, int n) {
static int r[3];
int i;
for (i=0; i<n; i++, a++, b++)
r[i]=*a+*b;
return r;
}
Does this solve
… the problem ?
int a[3]={1,2,3};
int b[3]={4,5,6};
int c[3]={0,1,2};
int d[3]={3,4,5};
int * rr1, *rr2;
rr1=add_vector3(a,b,3);
rr2=add_vector3(c,d,3);
print_vector(rr1,3); NO !
print_vector(rr2,3);
Dynamic memory allocation
• Variable definitions in C: the C compiler automatically allocates the
correct amount of storage (1-n memory locations) where the
variable will be stored -> this happens before the execution of the
actual program starts
• Sometimes it can be useful to dynamically allocate storage while a
program is running:
• Suppose we have a program that is designed to read in a set of
data from input into an array in memory but we don’t know how
many data items there are until the program starts execution. We
have three choices:
– Define the array to contain the maximum number of possible elements
at compile time.
– Use a variable-length array to dimension the size of the array at
runtime.
– Allocate the array dynamically using one of C’s memory allocation
routines.
malloc()
• <stdlib.h>
• void * malloc(int n);
• malloc allocates n bytes of memory and returns a pointer
to them if the allocation was succesful, NULL otherwise
• Before using the pointer returned by malloc, it has to be
checked if it is not NULL !!
• The pointer returned by malloc is of the generic type void
*; it has to be converted to a concrete pointer type
malloc() Example1
#include <stdlib.h>
char *line;
int linelen;
getline(line, linelen);
malloc() Example 2
char *somestring=“how are you”;
char *copy;
...
copy = (char *) malloc(strlen(somestring) + 1);
strcpy(copy, somestring);
Checking what malloc returns !
• When malloc is unable to allocate the requested memory, it returns a null
pointer. Therefore, whenever you call malloc, it's vital to check the returned
pointer before using it !
void fct(void) {
int *p;
p=(int*) malloc(10*sizeof(int));
return;
}
int * fct(void) {
int *p; YES !
p=(int*) malloc(10*sizeof(int));
// fill p with values . . .
return p;
}
int * fct(void) { NO !
int p[10];
// fill p with values . . .
return p;
}
Exercise: different versions of
adding 2 vectors
int * add_vector4(int *a, int *b, int n) {
int * r;
r=(int *) malloc(sizeof (int) * n);
if (r==NULL) exit(1);
int i;
for (i=0; i<n; i++, a++, b++)
r[i]=*a+*b;
return r;
}
…
int a[3]={1,2,3};
int b[3]={4,5,6};
int * rr;
rr=add_vector4(a,b,3);
print_vector(rr,3);
free()
• Dynamically allocated memory is deallocated with the free function. If p
contains a pointer previously returned by malloc, you can call
• free(p);
• which will ``give the memory back'' to the heap of memory from which
malloc requests are satisfied.
• the memory you give back by calling free() is immediately usable by other
parts of your program. (Theoretically, it may even be usable by other
programs.)
• When your program exits, any memory which it has allocated but not freed
should be automatically released by the operating system.
• Once you've freed some memory you must remember not to use it any
more. After calling free(p) it is probably the case that p still points at the
same memory. However, since we've given it back, it's now ``available,'' and
a later call to malloc might give that memory to some other part of your
program.
Structures and pointers
• Structure pointers are just like pointers to ordinary variables. The
declaration
• struct point *pp;
• says that pp is a pointer to a structure of type struct point. If pp
points to a point structure, *pp is the structure, and (*pp).x and
(*pp).y are the members.
• To use pp:
• struct point origin, *pp;
• pp = &origin;
• printf("origin is (%d,%d)\n", (*pp).x, (*pp).y);
• The parentheses are necessary in (*pp).x because the precedence
of the structure member operator . is higher then *. The expression
*pp.x means *(pp.x), which is illegal here because x is not a pointer.
Pointers to structures
• Pointers to structures are so frequently used that an alternative
notation is provided as a shorthand. If p is a pointer to a structure,
then referring to a particular member can be done by:
• p->member-of-structure
• Equivalent with (*p).member-of-structure
• printf("origin is (%d,%d)\n", pp->x, pp->y);
• Both . and -> associate from left to right, so if we have
• struct rect r, *rp = &r;
• then these four expressions are equivalent:
r.pt1.x
rp->pt1.x
(r.pt1).x
(rp->pt1).x
Precedence of operators
• The structure operators . and ->, together with () for function calls and [] for
subscripts, are at the top of the precedence hierarchy and thus bind very
tightly.
• For example, given the declaration
• struct {
• int len;
• char *str;
• } *p;
• then ++p->len increments len, not p, because the implied
parenthesization is ++(p->len) .
• Parentheses can be used to alter binding: (++p)->len increments p before
accessing len, and (p++)->len increments p afterward. (This last set of
parentheses is unnecessary.
• *p->str fetches whatever str points to;
• *p->str++ increments str after accessing whatever it points to (just like
*s++)
• (*p->str)++ increments whatever str points to
• *p++->str increments p after accessing whatever str points to.
Pointer arrays. Pointers to Pointers
• Since pointers are variables themselves,
they can be stored in arrays just as other
variables can
Pointers vs Multidimensional arrays
• int a[10][20];
• int *b[10];
• a[3][4] and b[3][4] are both syntactically legal references to an int.
• a is a true two-dimensional array: 200 int-sized locations have been
set aside, and the conventional rectangular subscript calculation 20
* row +col is used to find the element a[row,col].
• For b, however, the definition only allocates 10 pointers and does
not initialize them; initialization must be done explicitly, either
statically or with code. Assuming that each element of b does point
to a twenty-element array, then there will be 200 ints set aside, plus
ten cells for the pointers. The important advantage of the pointer
array is that the rows of the array may be of different lengths. That
is, each element of b need not point to a 20 element vector; some
may point to two elements, some to fifty, and some to none at all.
Pointers vs Multidimens arrays
• char *name[] = { "Illegal month", "Jan", "Feb", "Mar" };
• char aname[][15] = { "Illegal month", "Jan", "Feb", "Mar" };
Program design example
• a program that will read an then sort a set of text lines
into alphabetic order
• Requirements:
– Program reads a number of lines, until EOF, but not more than
MAXLINES=5000
– Each line may have a different number of characters, but not
more than MAXLEN=1000
– Program sorts lines in alphabetic order
– Program displays sorted lines
• How to approach program design problems:
– Data structures
– Algorithms
– Functions
Recall: Sorting algorithm
// sort an array of integers into ascending order
main
calls
calls
int main(void) {
int nlines; /* number of input lines read */
if ((nlines = readlines(lineptr, MAXLINES)) >= 0) {
sort(lineptr, nlines);
writelines(lineptr, nlines);
return 0;
} else {
printf("error: input too big to sort\n");
return 1;
}
}
Implementing the functions
• If a function corresponds to a problem which is still
complex, split it in other subproblems (functions)
• Top-down decomposition
• Stepwise refinement
Example: decomposing readlines()
• Readlines:
– repeatedly: reads a line from stdin, allocates a buffer of the exact
line length and copies there the input, stores pointer to buffer in
current element of lineptr
most least
Sign bit significant or significant or
high-order bit low-order bit
1*2^0+0*2^1+1*2^2=5
Binary representation of
integers
• Negative integers:
1 1 1 1 1 1 1 0 1 1
most least
Sign bit significant or significant or
high-order bit low-order bit
0 0 0 0 0 0 0 0 1 1 0 0 1
a=0x19
0 0 0 0 0 0 1 0 0 1 1 0 1 b=0x4d
0 0 0 0 0 0 0 0 0 1 0 0 1 a&b=0x9
Exercise: even or odd
• testing if an integer is even or odd, using bitwise operations:
• the rightmost bit of any odd integer is 1 and of any even integer
is 0.
int n;
if ( n & 1 )
printf(“odd”);
else
printf(“even”);
Bitwise Inclusive-OR (OR)
b1 b2 b1|b2 int a=25;
0 0 0 int b=77;
0 1 1 printf(“%x %x %x”,a,b,a|b);
1 0 1
1 1 1
0 0 0 0 0 0 0 0 1 1 0 0 1 a=0x19
0 0 0 0 0 0 1 0 0 1 1 0 1 b=0x4d
0 0 0 0 0 0 1 0 1 1 1 0 1 a|b=0x5d
Bitwise vs boolean !
• AND: bitwise: &, boolean: &&
• OR: bitwise: |, boolean: ||
0 1 1 printf(“%x %x %x”,a,b,a^b);
1 0 1
1 1 0
0 0 0 0 0 0 0 0 1 1 0 0 1
a=0x19
0 0 0 0 0 0 1 0 0 1 1 0 1 b=0x4d
0 0 0 0 0 0 1 0 1 0 1 0 0 a^b=0x54
The Ones Complement Operator
b1 ~b1
int a=25;
0 1
printf(“%x %x”,a,~a);
1 0
0 0 0 0 0 0 0 0 1 1 0 0 1 a=0x19
1 1 1 1 1 1 1 1 0 0 1 1 0 ~a=0xffffffe6
Usage: Masking bits
• A mask is a bit pattern with some bits set to on (1) and some bits to off
(0).
• Example:
• int MASK = 2; // 00000010, with only bit number 1 nonzero.
• Masking bits:
• flags = flags & MASK;
• all the bits of flags (except bit 1) are set to 0 because any bit combined
with 0 using the & operator yields 0. Bit number 1 will be left unchanged.
(If the bit is 1, 1 & 1 is 1; if the bit is 0, 0 & 1 is 0.) This process is called
"using a mask" because the zeros in the mask hide the corresponding bits
in flags.
• you can think of the 0s in the mask as being opaque and the 1s as being
transparent. The expression flags & MASK is like covering the flags bit
pattern with the mask; only the bits under MASK's 1s are visible
Usage: Turning bits on
• Turn on (set to 1) particular bits in a value while leaving the remaining bits
unchanged.
• Example: an IBM PC controls hardware through values sent to ports. To
turn on a device (i.e., the speaker), the driver program has to turn on the
1 bit while leaving the others unchanged.
• This can be done with the bitwise OR operator.
• The MASK has bit 1 set to 1, other bits 0
• int MASK = 2; // 00000010, with only bit number 1 nonzero.
• The statement
• flags = flags | MASK;
• sets bit number 1 in flags to 1 and leaves all the other bits unchanged.
This follows because any bit combined with 0 by using the | operator is
itself, and any bit combined with 1 by using the | operator is 1.
Usage: Turning bits off
• Turn off (set to 0) particular bits in a value while leaving the
remaining bits unchanged.
• Suppose you want to turn off bit 1 in the variable flags.
• The MASK has bit 1 set to 1, other bits 0
• int MASK = 2; // 00000010, with only bit number 1
nonzero.
• The statement:
• flags = flags & ~MASK;
• Because MASK is all 0s except for bit 1, ~MASK is all 1s except for
bit 1. A 1 combined with any bit using & is that bit, so the statement
leaves all the bits other than bit 1 unchanged. Also, a 0 combined
with any bit using & is 0, so bit 1 is set to 0 regardless of its original
value.
Usage: Toggling bits
• Toggling a bit means turning it off if it is on, and turning it on if it is off.
• To toggle bit 1 in flag:
• The MASK has bit 1 set to 1, other bits 0
• int MASK = 2; // 00000010, with only bit number 1 nonzero.
• flag = flag ^ MASK;
• You can use the bitwise EXCLUSIVE OR operator to toggle a bit.
• The idea is that if b is a bit setting (1 or 0), then 1 ^ b is 0 if b is 1 and is
1 if b is 0. Also 0 ^ b is b, regardless of its value.
• Therefore, if you combine a value with a mask by using ^, values
corresponding to 1s in the mask are toggled, and values corresponding to
0s in the mask are unaltered.
Usage: Checking value of a bit
• For example: does flag has bit 1 set to 1?
• you must first mask the other bits in flag so that you compare only bit 1 of
flag with MASK:
• if ((flag & MASK) == MASK)
•
The Left Shift Operator
•the bits contained in the
value are shifted to the left a
number of places (bits) int a=25;
•Bits that are shifted out
through the high-order bit of printf(“%x %x”,a,a<<1);
the data item are lost,
• 0s are always shifted in
through the low-order bit of
the value.shifted to the left.
Associated with this
Bit
lost 0 0 0 0 0 0 0 0 1 1 0 0 1 a : 0x19
0 0 0 0 0 0 0 1 1 0 0 1 0 a<<1 : 0x32
Exercise: multiply with 2
• Left shifting has the effect of multiplying the value that is shifted by two.
• Multiplication of a value by a power of two: left shifting the value the
appropriate number of places
int a;
scanf("%i",&a);
printf("a multiplied with 2 is %i \n",a<<1);
printf("a multiplied with 4 is %i \n",a<<2);
The Right Shift Operator
•Shifts the bits of a value to the right.
•Bits shifted out of the low-order bit of int a=25;
the value are lost.
•Right shifting an unsigned value or a printf(“%x %x”,a,a>>1);
signed positive value always results
in 0s being shifted in on the left
Bit
lost
0 0 0 0 0 0 0 0 1 1 0 0 1 a : 0x19
0 0 0 0 0 0 0 0 0 1 1 0 0 a>>1 : 0xc
Right shift of negative integers
•If the sign bit is 1, on some machines 1s are shifted in, and
on others 0s are shifted in.
•This former type of operation is known as an arithmetic right
shift, whereas the latter is known as a logical right shift.
•Never make any assumptions about whether a system
implements an arithmetic or a logical right shift. A program
that shifts signed values right might work correctly on one
system but fail on another due to this type of assumption.
Bit
lost
1 0 0 0 0 0 0 0 1 1 0 0 1
? 1 0 0 0 0 0 0 0 1 1 0 0
Example: extract groups of bits
• Example: an unsigned long value is used to represent color values, with
the low-order byte holding the red intensity, the next byte holding the green
intensity, and the third byte holding the blue intensity.
• You then want to store the intensity of each color in its own unsigned char
variable.
n
Exercise: printbits
• printbits(x,p,n): prints the n-bit field of x that begins at position
p. We assume that bit position 0 is at the right end and that n and p are
positive values.
31
31 30 23 22 2 1 0
int main(void)
{
float f=3.5;
unsigned int *ip=&f;
• Bibliography:
• [Kochan, chap 16.1, 16.2]
• [Kernighan&Ritche, chap 7.1, 7.2]
• [C Primer, chap 8]
Standard Input and Output
• input and output devices: such as keyboards, disk drives, printers,
screen.
• The C language itself does not have any special statements for
performing input/output (I/O) operations; all I/O operations in C
must be carried out through function calls.
• These functions are contained in the standard C library:
• #include <stdio.h>
• Advantages:
– Portability: they work in a wide variety of computer environments
– General character: they generalize to using files for I/O
• Disadvantage:
– Less performance: they don't take advantage of features peculiar to a
particular system.
Kinds of Standard I/O functions
• Character I/O
– getchar, putchar
• Formatted I/O
– scanf, printf
Character I/O example
• /* echo.c -- repeats input */
• #include <stdio.h>
• int main(void) {
• char ch;
• while ((ch = getchar() ) != ‘*’)
• putchar(ch);
• return 0;
• }
I/O streams
• C treats input and output devices the same as it treats
regular files on storage devices. In particular, the keyboard
and the display devices are treated as files opened
automatically by every C program.
• Conceptually, the C program deals with a stream instead
of directly with a file. A stream is an idealized flow of data
to which the actual input or output is mapped.
• Keyboard input is represented by a stream called stdin,
and output to the screen is represented by a stream called
stdout. The getchar(), putchar(), printf(),
and scanf() functions are all members of the standard
I/O package, and they deal with these two streams.
EOF
• One implication of I/O streams is that you can
use the same techniques with keyboard input as
you do with files.
• For example, a program reading a file needs a
way to detect the end of the file so that it knows
where to stop reading. Therefore, C input
functions come with a built-in, end-of-file
detector. Because keyboard input is treated like
a file, you should be able to use that end-of-file
detector to terminate keyboard input, too.
– CTRL-Z is EOF for keyboard input
Character I/O example + EOF
•/* echo_eof.c -- repeats input */
•#include <stdio.h>
•int main(void) {
• char ch;
• while ((ch = getchar() ) != EOF)
• putchar(ch);
• return 0;
•}
Buffered/unbuffered input
/*echo.c -- repeats input */
#include <stdio.h>
int main(void) {
char ch;
while ((ch = getchar()) != ‘*’)
putchar(ch);
return 0;
}
References
Reference [Kochan]
(to look (to!)look up only !)
up only
Some interesting scanf
conversions
scanf Examples (1)
• Whitespace characters inside a format string match an
arbitrary number of whitespace characters on the input. So,
the call
• scanf ("%i%c", &i, &c);
• with the line of text
• 29 w
• assigns the value 29 to i and a space character to c
because this is the character that appears immediately after
the characters 29 on the input.
• If the following scanf call is made instead:
• scanf ("%i %c", &i, &c);
• and the same line of text is entered, the value 29 is assigned
to i and the character 'w’ to c because the blank space in
the format string causes the scanf function to ignore any
leading whitespace characters after the characters 29 have
been read.
scanf Examples (2)
• An asterisk can be used to skip fields. If the scanf call
• scanf ("%i %5c %*f %s", &i1, text, string);
• is executed and the following line of text is typed in:
• 144abcde 736.55 (wine and cheese)
• the value 144 is stored in i1; the five characters abcde are
stored in the character array text; the floating value
736.55 is matched but not assigned; and the character
string "(wine" is stored in string, terminated by a null.
• The next call to scanf picks up where the last one
left off. So, a subsequent call such as scanf ("%s %s
%i", string2, string3, &i2); has the effect of storing
the character string "and" in string2 and the string
"cheese)" in string3 and further waits for an integer to be
typed in.
scanf Examples (3)
• The scanf call
• scanf ("%[^/]", text);
• indicates that the string to be read can consist of any
character except for a slash. Using the preceding call on the
following line of text
• (wine and cheese)/
• has the effect of storing the string "(wine and cheese)" in text
because the string is not terminated until the / is matched (which
is also the character read by scanf on the next call).
• To read an entire line from the terminal into the character array
buf, you can specify that the newline character at the end of the
line is your string terminator:
• scanf ("%[^\n]\n", buf);
• The newline character is repeated outside the brackets so that
scanf matches it and does not read it the next time it’s called.
(Remember, scanf always continues reading from the character
that terminated its last call.)
scanf Examples (4)
• When a value is read that does not match a value expected by scanf
(for example, typing in the character x when an integer is expected),
scanf does not read any further items from the input and immediately
returns. Because the function returns the number of items that
were successfully read and assigned to variables in your program,
this value can be tested to determine if any errors occurred on the
input. For example, the call
• if ( scanf ("%i %f %i", &i, &f, &l) != 3 )
• printf ("Error on input\n");
• tests to make certain that scanf successfully read and assigned three
values. If not, an appropriate message is displayed.
• Remember, the return value from scanf indicates the number of
values read and assigned, so the call
• scanf ("%i %*d %i", &i1, &i3)
• returns 2 when successful and not 3 because you are reading and
assigning two integers (skipping one in between). Note also that the
use of %n (to obtain the number of characters read so far) does not
get included in the value returned by scanf.
Redirecting I/O to a file
• Sometimes we want programs to take input from a file
instead from the keyboard or to write results in a file
instead on the screen
• Both read and write file operations can be easily
performed under many operating systems, such as Unix
and Windows, without anything special being done at all
to the program through I/O redirecting
• stdio functions in C have a general character, they work
on abstract streams
• There are also special file access mechanisms are
provided in C, but these will be discussed next semester
Redirect output
• For example, if you want to write all your program results
into a file called data.txt:
• all that you need to do under Unix or Windows, if running in a
terminal window, is to redirect the output from the program prog
into the file data.txt by executing the program with the following
command at the command prompt:
prog > data.txt
• This command instructs the system to execute the
program prog but to redirect the output normally written
to the terminal into a file called data.txt instead.
• Any values displayed by putchar or printf do not
appear on screen but are instead written into the file
called data.txt.
Redirect input
• If you want your program to read all input from a file
instead of the keyboard:
• You can have the program get its input from a file called
input.txt, for example, by redirecting the input when
the program is executed. If the program is called prog,
the following command line works:
prog < input.txt
• Any call to a function that normally reads data from your
window, such as scanf and getchar, will be made to
read its information from the file input.txt
Redirect both input and output
• Redirect both input and output
prog < input.txt > data.txt
I/O redirection example
• /* pecho.c -- repeats input
*/ • F1.txt
•
• #include <stdio.h>
• int main(void) { • Bla bla bla
• char ch; • Oh la la *
• while ((ch = getchar()) != • Hoo hoo hoo
‘*’)
• putchar(ch);
• return 0;
• }