C
#include <stdio.h>int main(){
printf ("hello class\n");return 0;
}
2
Working environment
• Linux, gcc
• We’ll work with c9.io website, which works with
ubuntu
• I recommend to install ubuntu too
• Also in tirgul
History
3
70’s – Development of UNIX. (Richie+Kernigham – Bell labs)
80’s – Large efficient code. (Stroustrup – Bell labs)
90’s – Language for the web. (Sun Microsystems)
Simple to convert to
machine code.VM
Fast and Efficient Secure and Safe
Welcome to C Easy to avoid bugs
Easy to Debug
C++C Java
History – C:
K&R 1st
ed. ('78)ANSI C
('89)C99 ('99)
C11(’11)
This course, without the VLA!
• First "standard"
• Default int
•Enums
•Return struct
•void
• //
• VLA
• variadic
macros
•inlining
•multithreading
•Anonymous
structs
• _Generic
5
C – Design Decisions
“Bare bones” – the language leaves maximal flexibility
with the programmer
Efficient code (operating systems)
Full control on memory & CPU usage
High-level
Type checking
High-level constructs
Portable
Standard language definition
Standard library
C – Warning Signs
6
No run-time checks
Array boundary overruns
Illegal pointers
No memory management
Programmer has to manage memory
First Program in C
7
// This line is a comment,
/* and this line also. */
// This line defines standard I/O library
#include <stdio.h>
// main – program entry point. Start form here
int main()
{ // {…} define a block
printf("Hello class!\n");
return 0;
}
7
Similar to java – you should know it already.
8
The basic syntax
Basic
9
• Case sensitive
• White-space not important.
• End statements with “;”
• Code block defined with “{” and “}”
• Return value from function using “return X;”
• String with “ " ”
• All lines below are legal:
int x,y;
x=5; {
x; } ;
Statements - conditional
10
if (expression)
//statement or block
else if (expression)
//statement or block
else (expression)
//statement or block
switch (integer value)
later...
Statements - loops
11
The usual suspects:
int x,y; //in ANSI C you cannot declare inside
the for!
for (x=0,y=0;x<10 && y<5;x++,x+=2)
//statement or block
while (condition)
//statement or block
do
//statement or block
while (condition)
Statically typed – each variable has a type. Declare by:
<type> <name>.
int x;
int x,y;
Optionally initialize (otherwise undefined!)
int x=0;
Variables
12
int x;
Undefined value: as in this example, can have any T(here T=int) value.
Undefined behavior: Everything may happen. Probably
won’t format your disk, but may very well give a hacker a
way to do it…
The biggest problem: often programs seems to work
fine although their behavior is undefined, and then…
Undefined – important!
13
Variables
14
Where to declare?
1. Inside a block (C89 - block beginning) , will be visible only
in block.
2. Outside all blocks – global - will be visible everywhere.
int x=0; // globalint main()
{ int x=1; //local hides global
{ int x=2; //local hides outer scope //x is 2
} //x is 1 again!
}
Scopes
15
• Code block defined with “{” and “}”.
• Only declarations inside current or outer scopes are visible.
• Declarations in inner scope hide declarations in outer
scopes:
• Outmost scope (global) had no brackets.
• Keep in mind that a function is also a scope.
int y=5,x=0; {
int x=y; //x is 5 {
int y; }
} // x is 0
Second Program
16
#include <stdio.h>int main() {
int i; // declares i as an integer int j = 0; // declares j as an integer,
// and initializes it to 0 // for( initial ; test condition ; update step ) for( i = 0; i < 10; ++i ) {
j += i; // shorthand for j = j + iprintf("%d %d %d\n", i, j, (i*(i+1))/2);
} return 0;
}
16
Running…
17
0 0 0
1 1 1
2 3 3
3 6 6
4 10 10
5 15 15
6 21 21
7 28 28
8 36 36
9 45 45
17
Functions
18
C allows to define functions
Syntax:
int power( int a, int b )
{
…
return 7;
}
Return typeParameter
declaration
Return
statement
18
Procedures
19
Functions that return void
void power( int a, int b )
{
…
return;
}
Return w/o value
(optional)
19
Example – printing powers
20
#include <stdio.h>
int power( int base, int n )
{
int i, p;
p = 1;
for( i = 0; i < n; i++ )
{
p = p * base;
}
return p;
}
int main()
{
int i;
for( i = 0; i < 10; i++ )
{
printf("%d %d %d\n",
i,
power(2,i),
power(-3,i) );
}
return 0;
}20
Functions Declaration
21
“Rule 1”: A function
“knows” only
functions which were
declared above it.
void funcA()
{
...
}
void funcB()
{
funcA();
}
void funcC()
{
funcB();
funcA();
funcB();
}
void funcA()
{
...
}
void funcB()
{
funcC();
}
void funcC()
{
funcB();
}
Error:
funcC is not
known yet.
21
Functions Declaration
void funcC(int param);
// or: void funcC(int);
void funcA()
{
}
void funcB()
{
funcC(7);
}
void funcC(int param)
{
}
Amendment to “Rule 1” : Use forward declarations.
22
Boolean variables – non!
23
int main()
{
int a = 5;
while(1)
{
if(!(a-3))
{
printf("** a=3 **\n");
break;
}
printf("a=%d\n",a--);
}
return 0;
}
24
Building a program in C:
Preprocessor, Compilation and Linkage
Building a program in C – Preprocessor
25
A text processor
Commands start with #
// copy & paste the file here
#include <stdio.h>
hello.c
Preprocessor
stdio.h
tmpXQ.i
(C code)
Building a program in C – Compiling
26
Takes input C-code and produces machine code (object
file)
The object file does not contain all external references: It
leaves names, such as “printf”, “area”, etc. as undefined
references
hello.c
Preprocessor Compiler
stdio.h
tmpXQ.i
(C code)
hello.o
(object
file)
Linking
27
Combines object file with external references into an
fully executable file, with no unresolved references
Main
Preprocessor,
Compiler
Main.c Main.o
Linker
libc.a
Link errors
28
Gcc: /media/sf_BitEagle_Projects/cbitcoin/test/testCBAddress.c:40:undefined reference to`CBNewByteArrayFromString‘
Visual studio:Error 1 error LNK2019: unresolved external symbol _foo referenced in function _main
c:\Users\ofirpele\documents\visual studio 2012\Projects\ConsoleApplication5\ConsoleApplication5\ConsoleApplication5.obj
ConsoleApplication5
29
The Preprocessor
Compilation in C
30
hello.c
Preprocessor Compiler
stdio.h
tmpXQ.i
(C code)
hello.o
(object
file)
Preprocessor
31
A single-pass program that:
1. Include header files
2. Expands macros
3. Control conditional compilation
4. Remove comments
Outputs – a code ready for the
compiler to work on.
Preprocessor
32
In linux with gcc, we can test what
the preprocessor does:
> gcc –E hello.c
will print the C code after running the
preprocessing
#include directive
33
#include "foo.h"
Include the file “foo.h”, from current directory
#include <stdio.h>
Include the file “stdio.h” from the standard
library directory (part of compiler installation)
Modules & Header files
34
Complex.c
// interface of function
int area (int x1,int y1, int x2, int y2);
...
Square.h
#include "Square.h"
#include <math.h>
// implementation
int area (int x1,int y1,int x2, int y2)
{
...
}
Square.c
#include "Square.h"
int main()
{
area (2,3, 5,6);
}
Main.c
Do all files get compiled every time we
build the program???
35
$ gcc –c Square.c –o Square.o
$ gcc –c Main.c –o Main.o
$ gcc Square.o Main.o –o Main
Main
Preprocessor
Compiler
Square.c Square.o
Main.c Main.o
Linker
libc.a
Header files
36
Header file contain
1. Definition of data types
2. Declarations of functions & constants
3. That are shared by multiple modules.
#include directive allows several
modules to share the same set of
definitions/declarations
#define directive
37
#define FOO 1
int x = FOO;
is equivalent to
int x = 1;
#define with arguments
38
#define SQUARE(x) x*x
b = SQUARE (a);
is the same as
b = a*a;
39
#define SQUARE (x) x*x
b = SQUARE (a+1);
c = SQUARE (a++);
Is it what we intended?
b = a+1*a+1;
//Actually: b = 2*a+1;
c = a++*a++;
//Actually: c = a*a; a+=2;
#define – cautions
#define – cautions
40
#define SQUARE (x) ((x)*(x))
b = SQUARE (a+1);
c = SQUARE (a++);
Is it what we intended?
b = ((a+1)*((a+1));
//Now ok
c = ((a++)*(a++));
//Did not help: c = a*a; a+=2;
#define
41
#define directive should be used with
caution!
Alternative to macros:
• Constants
enum { FOO = 1 };
or
const int FOO = 1;
• Functions – inline functions (C99,C++)
#define
42
Multi-line:
All preprocessor directive effect one line (not c statement).
To insert a line-break, use “\”:
BAD:
#define x (5 +5)
// x == 10 !
GOOD:
#define x (5 + \
5)
// x == 10 !
#if directive
43
Allows to have conditional compilation
#if defined(DEBUG)
// compiled only when DEBUG exists
printf("X = %d\n", X);
#endif
#ifndef – for header safety
44
Complex.h:
struct Complex
{
...
MyStuff.h:
#include "Complex.h"
Main.c:
#include "MyStuff.h"
#include "Complex.h"
Error:
Complex.h:1: redefinition
of `struct Complex'
#ifndef – header safety
45
Complex.h (revised):
#ifndef COMPLEX_H
#define COMPLEX_H
struct Complex
{
...
#endif
Main.c:
#include "MyStuff.h"
#include "Complex.h" // no error this time
#pragma once – header safety
46
Complex.h (revised):
#pragma once
struct Complex
{
...
Main.c:
#include "MyStuff.h"
#include "Complex.h" // no error this time
Preprocessor – summary
47
• Text processing program.
• Does not know c rules
• Operates before compilation, output passed to
compiler.
• Can do copy and paste / cut
• #include paste the included file here Commonly
included file (.h by convention) contains forward
declarations
• #define copy the macro body, paste it where macro
name appears - constants, simple "functions"
• #if condition not fulfilled, cut the code - Conditional
compilation – e.g. debugging code
48
Debug/Test mode vs
Release mode
49
Debug/Test mode vs Release mode
#include <assert.h>#define MAX_INTS 100int main() {int ints[MAX_INTS];// i should be in bounds, but is it really?i = foo(<something complicated>); // safety assertionsassert(i>=0); assert(i<MAX_INTS);ints[i] = 0;...
50
#include <assert.h>#define MAX_INTS 100int main() {int ints[MAX_INTS];// i should be in bounds, but is it really?i = foo(<something complicated>); // safety assertionsassert(i>=0); assert(i<MAX_INTS);ints[i] = 0;...
Debug/Test mode vs Release mode
51
#include <assert.h>#define MAX_INTS 100int main() {int ints[MAX_INTS];// i should be in bounds, but is it really?i = foo(<something complicated>); // safety assertionsassert(i>=0); assert(i<MAX_INTS);ints[i] = 0;...
#define NDEBUG
52
assert
// bad, foo() will not be called// if the compiler removes the assert() // if NDEBUG is definedassert(foo() == 0);
// goodint errCode = foo();assert(errCode == 0);
53
Use for:• Catching bugs
Don't use for:• checking malloc, user input,...
assert
assert.h
54
#include <assert.h>
// Sqrt(x) - compute square root of x
// Assumption: x non-negative
double sqrt(double x )
{
assert( x >= 0 ); // aborts if x < 0
…
assert.h
55
// procedure that actually prints error message
void __assert(char* file,int line,char* test);
#ifdef NDEBUG
#define assert(e) ((void)0)
#else
#define assert(e) \
((e) ? (void)0 : \
__assert(__FILE__, __LINE__, #e))
#endif
assert.h
56
• Important coding practice
• Declare implicit assumptions
• Sanity checks in code
• Check for violations during
debugging/testing
57
Compilation
Compilation
58
• Translate the c code to machine code.
• Every machine architecture has a different
code. Need separate compilation.
• x86 : older but still common PCs “32-bit”
(Intel/AMD)
• x64 : newer PCs “64-bit” (Intel/AMD)
• ARM : (many versions) Phones, tablets
(ARM)
• Translated code is an “executable” – the OS
can load it to the machine memory, and the let
the CPU do whatever you wrote in the code.
“Assembly”
59
int y=2; int mult(int x) {
return x*y;
mov eax,dword ptr [x]
imul eax,dword ptr [1177000h]
} int main() {
return mult(5);
push 5
call 11711A4h
}
Only part of the assembly code is shown here.
Actually each command has binary code, and the sequence of these code
is the object file.
Compiling warnings
Compiling warnings
61
Add “-Wall” flag to catch things like this:
if (i=3) { //bug, we meant i==3
…
}