Transcript Lecture 3

CS 3034 Lecture 3
Introduction To C
Many of these slides were originally
written by Henning Schulzrinne,
Columbia University
C, C++, and Java
 C
 Developed by Dennis Ritchie in late 1960s/ early 1970s
 Designed for systems programming
 Original purpose was to develop UNIX
 Low level enough for OS programming, high level enough for code to be
reasonably portable across hardware platforms (can’t do this in Assembly)
 Applications could be written in Fortran, PL/I, etc.
 Still the standard in systems programming
 Linux kernel is strictly in C
2
Schulzrinne
C, C++, and Java
 C++
 Bjarne Stroustrup (Bell Labs), 1980s
 Superset of C; note the pun in the name
• Adds support for OOP
• Adds higher-level I/O and other functionality
3
Schulzrinne
C, C++, and Java
 Java
 James Gosling in 1990s, originally for embedded systems, found many
uses
 object-oriented, like C++
 ideas and most syntax from C / C++
 more platform independent than C++ due to use of JVM
 easier to use than C++ but gives up some of C++'s low-level functionality
 protects from many typical C/C++ errors
4
Schulzrinne
C vs. C++





Both very common in Windows, Linux
C++ adds OOP capabilities to C
Both less portable than Java
C++ has simpler I/O than C
Both can be hard to read, and both encourage
"clever" programming over code readability
 Fewer “guard rails” than Java; it is much easier to
make serious logic errors in C/C++ than in Java
5
Schulzrinne
K&R
 This book, known as “K & R,” is the Bible of C and served
as the informal standard for C in the early days.
 K & R is a detailed reference book. You don’t need it and
generally wouldn’t find it very useful for this course.
However, if you talk about C to other programmers, it
won’t be long before someone mentions it, so you need to
know what it is. If you ever work as a C programmer,
everyone will expect you to have a copy.
6
Introduction To C
 These introductory slides are intended for students who
are already proficient in Java.
 I will skip over many topics that are substantially the same
in C as in Java.
7
Why Learn C / C++?
 C++ is very widely used in application programming, C in
systems programming
 Support both high-level and low-level programming
 OS: user interface to kernel to device driver
 Better control of low-level mechanisms
 memory allocation, specific memory locations
 Performance often better than Java
 compiled, not run on a VM
 usually more predictable due to lack of JVM layer (also: C vs. C++)
8
Schulzrinne
Why learn C, cont’d.
 Much older code is written in C or C++
 Linux, *BSD
 Windows
 Embedded systems are usually written in C
Schulzrinne
Executing C programs
 Scripting languages are usually interpreted
 perl (python, Tcl) reads script, and executes it
 sometimes, just-in-time compilation – invisible to
user
 Java programs semi-interpreted:
 javac converts foo.java into foo.class
 not machine-specific
 byte codes are then interpreted by JVM
 C programs are normally compiled and linked:
 gcc converts foo.c into a.out or, with an
extra parameter to the compiler,
just foo
Schulzrinne
 a.out or foo is executed by OS and hardware
C vs. Java
 Java program
 collection of classes
 class containing main method is starting class
 running java StartClass invokes
StartClass.main method
 JVM loads other classes as required
Schulzrinne
C program
 collection of functions
 one function – main() – is starting
function
 running executable (default name a.out)
starts main function
 typically, single program with all user code
linked in – but can be dynamic libraries (.dll,
.so)
Schulzrinne
C vs. Java
public class hello
{
public static void main
(String args []) {
System.out.println
("Hello world");
}
}
Schulzrinne
#include <stdio.h>
int main(int argc, char
*argv[])
{
puts("Hello, World");
return 0;
}
Basic C Output
puts(string parameter)
putchar (char parameter)
printf with formatting codes
codetype format
d int decimal (base ten) number
o int octal number (no leading '0' supplied in printf)
x or X
int hexadecimal number (no leading '0x' supplied in printf; accepted if present in
scanf) (for printf, 'X' makes it use upper case for the digits ABCDEF)
ld long decimal number ('l' can be applied to any of the above to change the type from 'int'
to 'long')
u unsigned decimal number
lu unsigned long decimal number
c
char [footnote]
single character
s
char pointer string
f
float [footnote]
number with six digits of precision
g
float [footnote]
number with up to six digits of precision
e
float [footnote]
number with up to six digits of precision, scientific notation
lf double [footnote] number with six digits of precision
lg double [footnote] number with up to six digits of precision
le http://www.cdf.toronto.edu/~ajr/209/notes/printf.html
double [footnote] number with up to six digits of precision, scientific notation
Basic C Output
printf formatting codes can take digit values to specify
precision
float PI = 3.14159;
printf("%4.3f\n", PI); //prints 4 digits, with 3 after the decimal point
Simple example
#include <stdio.h>
int main(void)
{
printf("Hello World. \n \t and you ! \n ");
/* print out a message */
return 0;
}
If you are using a text editor or IDE in which the console screen
disappears after execution, add getchar();
After the output. This will cause the program to wait for input so
that the console stays open.
Schulzrinne
Dissecting the example
 #include <stdio.h>
 include header file stdio.h, which contains code
needed for the printf()
 # lines processed by pre-processor
 No semicolon at end
 Lower-case letters only – C is case-sensitive
 void main(void){ … } is the only code executed
 printf(" /* message you want printed */ ");
 \n = newline, \t = tab
 \ in front of other special characters within printf.
Schulzrinne

printf("Have you heard of \"The Rock\" ? \n");
Executing the C program
int main(int argc, char argv[])
 argc is the argument count
 argv is the argument vector
 array of strings with command-line arguments
 the int value is the return value
 convention: 0 means success, > 0 some error
 can also declare as void (no return value)
Schulzrinne
Executing a C program
 Name of executable + space-separated
arguments
 $ ./myprog 1 23 ‘third arg’
argv
argc
4
a.out
Schulzrinne
1
23
"third arg"
Executing a C program
 If no arguments, simplify:
int main() {
puts("Hello World");
exit(0);
}
 Uses exit() instead of return – same
thing.
Schulzrinne
The C compiler gcc
 There are many compilers available for C, but use gcc, the
gnu compiler collection. Includes compilers for many
languages, plus an assembler. Since C and C++ compilers
are not fully standardized, it is important that you use the
same compiler I use to grade your work.
 Don’t confuse the compiler with an IDE. The compiler only
compiles. IDEs contain text editors, etc. and use
compilers when needed.
 Use any IDE you want for this course. Some of my demos
will use Geany, which is available for Windows, Linux, and
OSX.
Schulzrinne
gcc
 If you use Linux or OSX, gcc was probably already
installed with your OS
 If it is not already installed in your Fedora VM or
other Fedora machine, install it this way:
sudo dnf install gcc
 For Windows, install mingw from
http://www.mingw.org/
 then find the gcc executable and *carefully* add the
directory to your path
 If you write your code on your own machine, recompile
and test it in the Fedora VM before you turn it in!
Schulzrinne
gcc
 C++ compilers will compile C code, but not the other way
around. At this point, you should deliberately compile as
C, not C++, to make sure you do not use C++ by accident.
 gcc invokes C compiler
 gcc translates C program into executable for some target
 default file name a.out
$ gcc -std=c11 -m32 -Wall hello.c
$ ./a.out
Hello, World!
-Wall adds warning messages
-std=c11 directs the compiler to treat the code using C 2011, the most recent
specification.
To give a better name to the executable, add -o and the desired file name, eg
gcc -std=c11 -m32 -Wall -o hello hello.c
Schulzrinne
The C compiler gcc
Most text editors have menu items to compile, build, and execute
programs, so that they can be used as lightweight IDEs. Often the
menu items will already have the right commands for gcc, based on
the filename extension c or cpp. If you have to set them, the right
commands are typically:
Compile: gcc -std=c11 -m32 -Wall -o "%e" "%f"
Execute: "./%e"
Error reporting in gcc
 Multiple sources
 preprocessor: missing include files
 parser: syntax errors
 assembler: rare
 linker: missing libraries
Schulzrinne
Error reporting in gcc
 If gcc gets confused, hundreds of
messages
 fix the first one, and then retry – ignore the
rest
 gcc will produce an executable with
warnings
 don’t ignore warnings – compiler choice is
often not what you had in mind
 Compilers can’t identify logic errors!
 if (x = 0)
Schulzrinne
vs. if
(x == 0)
gcc errors
 Produces object code for each module
 Assumes references to external names
(variables, etc from imported files) will be
resolved later
 Undefined names will be reported when
linking:
undefined symbol
first referenced in file
_print
program.o
ld fatal: Symbol referencing errors
No output written to file.
Schulzrinne
C preprocessor
 The C preprocessor (cpp) is a macroprocessor which
 manages a collection of macro definitions
 reads a C program and transforms it
 Example:
#define MAXVALUE 100
#define check(x) ((x) < MAXVALUE)
if (check(i) { …}
becomes
if ((i) < 100)
Schulzrinne
{…}
C preprocessor
 Preprocessor directives start with # at
beginning of line:
 define new macros
 input files with C code (typically, definitions)
 conditionally compile parts of file
 gcc –E shows output of preprocessor
 Can be used independently of compiler
Schulzrinne
C preprocessor
#define name const-expression
#define name (param1,param2,…) expression
#undef symbol
 replaces name with constant or expression
 textual substitution
 symbolic names for global constants
 type-independent code
Schulzrinne
C preprocessor –file inclusion
#include "filename.h"
#include <filename.h>
 inserts contents of filename into file to be compiled
 "filename" relative to current directory
 <filename> relative to /usr/include
 gcc –I flag to re-define default
 import function prototypes (cf. Java import)
 Examples:
#include <stdio.h>
#include "mydefs.h"
#include "/home/alice/program/defs.h"
Schulzrinne
Comments
 /* any text until */
 // C++-style comments – careful!
– Only added to C in 1999
 Convention for longer comments:
/*
* AverageGrade()
* Given an array of grades, compute the average.
*/
 Avoid **** boxes – hard to edit, usually
look ragged.
Schulzrinne
Naming Conventions
 Naming conventions are looser for C than
for Java.
– Some programmers use camel case, as in
Java: myVariable
– Others use the traditional C style, with
underscores: my_variable
– Use all caps for constants: PI
– Most important: be consistent within
your own code
Schulzrinne
type
bytes
(typ.)
range
char
1
-128 … 127
short
2
-65536…65535
int
4
(usually)
-2,147,483,648 to 2,147,483,647
long
8
264
float
4
3.4E+/-38 (7 digits)
double
8
1.7E+/-308 (15 digits)
Schulzrinne
Numeric data types
Remarks on data types
 Range differs – int is usually 32 bits, may
be 16 or 64 on some systems with come
compilers. Try this:
– printf("%lu\n", sizeof(int)); //lu means “long
unsigned”
 Also, unsigned versions of integer types
 same bits, different interpretation
 char = 1 ASCII "character"
Schulzrinne
Scanf
Opposite of printf, with formatting codes
Take the & in format codes on faith for now.
If you enter a string, scanf stops reading at
any whitespace
Schulzrinne
Example
#include <stdio.h>
void main(void)
{
int nstudents = 0; /* Initialization, required */
printf("How many students does Columbia have ?:");
scanf ("%d", &nstudents); /* Read input */
printf("Columbia has %d students.\n", nstudents);
return ;
}
$ How many students does Columbia have ?: 20000 (enter)
Columbia has 20000 students.
Schulzrinne
Type conversion
#include <stdio.h>
void main(void)
{
int i,j = 12;
/* i not initialized, only j */
float f1,f2 = 1.2; /* f1 not initialized, only f2 */
printf("%d %d %f %f\n", i, j, f1, f2);
i = (int) f2;
/* explicit: i <- 1, 0.2 lost */
f1 = i;
/* implicit: f1 <- 1.0 */
printf("%d %d %f %f\n", i, j, f1, f2);
f1 = f2 + (int) j; /* explicit: f1 <- 1.2 + 12.0 */
f1 = f2 + j;
/* implicit: f1 <- 1.2 + 12.0 */
printf("%d %d %f %f\n", i, j, f1, f2);
}
Schulzrinne
Explicit and implicit conversions
 Implicit: e.g., s = a (int) + b (char)
 Promotion: char -> short -> int -> …
 If one operand is double, the other is made
double
 If either is float, the other is made float, etc.
 Explicit: type casting – (type)
 Almost any conversion does something – but
not necessarily what you intended
Schulzrinne
Type conversion
int x = 100000;
short s;
s = x;
printf("%d %d\n", x, s);
100000 -31072
Cast to short preserves the lower 16 bits, which are 1000011010100000,
as a twos complement representation. Decimal value of twos
complement value 1000011010100000 is -31072
Schulzrinne
booleans
Booleans in C require #include <stdbool.h>
There is no printf formatting code for booleans, so you have to be
a little creative.
#include <stdio.h>
#include <stdbool.h>
int main(void)
{
bool b = false;
printf("%s\n", b?"true":"false");
return 1;
}
Or
puts(b?"True":"False");
User-defined types
 typedef gives names to types:
typedef short int small_number;
typedef unsigned char byte;
typedef char String[100];
small_number x;
byte b;
String name;
Schulzrinne
Constants
The const keyword (equivalent to final in Java) makes a
value a constant
const float PI = 3.14159;
PI = 5;
// syntax error!
Enumerated types
 Just syntactic sugar for ordered collection of
integer constants:
typedef enum {
Red, Orange, Yellow
} Color;
is like
#define Red 0
#define Orange 1
#define Yellow 2
Schulzrinne
Enumerated types
This more Java-like syntax also works:
enum monster {ZOMBIE, VAMPIRE, YETI};
enum monster curr_monster = VAMPIRE;
Output as int, or use conditionals to print strings
printf("%d\n", currmonster);
Or
if(curr_monster == VAMPIRE) puts ("Watch out, he's a
Vampire!");
Etc.
The switch statement
 Allows choice based on a single value
switch(expression) {
case const1: statements1; break;
case const2: statements2; break;
default: statementsn;
}
 Effect: evaluates integer expression
– But more things count as ints than you might
think: enums, chars, etc.
 looks for case with matching value
 executes corresponding statements (or
defaults)
Schulzrinne
switch
#include <stdio.h>
void main(void)
{
typedef enum {ZOMBIE, VAMPIRE, WEREWOLF} Monster;
Monster m = WEREWOLF;
switch(m) {
case ZOMBIE:
printf("Zombie; get shotgun\n");
break;
case VAMPIRE:
printf("Vampire; get wood stakes\n");
break;
case WEREWOLF:
printf("Werewolf; get chocolate\n");
break;
default:
printf("Unknown monster; call in Godzilla\n");
}
}