1 C Intro
1 C Intro
• Thread and Graphic (2D and 3D) programming, Refactoring, TDD, Qt, …
References
• P. Deitel, H. Deitel, C++: How to Program, 9th
Edition, Prentice Hall, 2011.
• filename.cpp
Simple C Program
• Examples:
// int is return data type // Simplest c program
// main is entrance function int main()
{
int main() return 0;
{ }
statement 1;
statement 1; /*
// …. Objective: print on screen
*/
return 0; #include <stdio.h> // preprocessor statements have not ;
} int main() welcome to c!!!
{
printf("welcome to c!!!");
return 0; // indicate that program ended successfully
}
Example
– Header file
#include <stdio.h> // (preprocessor )
– Constant
#define PI 3.14 // PI constant (preprocessor )
– Main function
– Variables
// calculating area of circle
– Input and output
int main()
– Process
{
/* variable definition */
float Radius;
float Area = 0;
// get radius of circle form user
printf("Enter Radius :\n");
scanf("%f", &Radius);
// calculating area of circle
Area = PI * Radius * Radius;
printf(“Area = %f", Area );
system("Pause");
return 0;
}
Variable declaration
• Before using a variable, you must declare it
Data_Type Identifier;
• int width; // width of rectangle
• float area; // result of calculating area stored in it
• char separator; // word separator
Data_Type Identifier = Initial_Value;
• int width = 10; // width of rectangle
• float area = 255; // result of calculating area stored in it
• char seperator = ‘,’; // word separator
Data_Type Identifier, Identifier, Identifier ,….;
• int width, length, temporary;
• float radius, area = 0;
Data types
• Minimal set of basic data types
– primitive data types
• int
• float
• double
• char
• Void
• Run-time
– E.g. division by zero
• Logical
– E.g. Overflow and Underflow
Integer constant value
• Base 10: 1 915 +8 -90
• Base 8: 074 0123 084
• Base 16: 0x1 0X5 0x7fab
• unsigned: 5000u 4U
• long: 123456789l 56L
• unsigned long: 536489ul
• long long : 5361254865LL 25lL
• Example :
– 0xABu 0123uL 017LL
floating-point constant value
• A floating-point value contains a decimal point
– 33.5 0.0 -657.983 .2 6.
• String
printf("string is array of char!!!");
printf("example of escape sequence is \n");
Constant
• Constants provide a way to define a variable which
cannot be modified by any other part in the code
– #define: without memory consume
– const: memory consume
• Assignment Operators
• Equality and Relational Operators
• Logical Operators
• Bitwise Operators
• Conditional Operator
• Comma Operator
• sizeof
Arithmetic Operators
• Unary Operator
Positive + a = +3;
Negative - b = -4;
Decrement -- i - -; Equivalent to i = i - 1
Arithmetic Operators
• Binary Operators
int a = 7, b;
float z;
b = 3, z = 3.500000
b = a / 2;
z = a / 2.0;
printf("b = %d, z = %f\n", b, z);
Modulus
• You could only use modulus (%) operation on
integer variables (int, long, char)
z = a % 2.0; // error
z = a % 0; // error
Modulus will result in the
remainder of a/2.
• Example 7 2
- a/2
int a = 7, b, c; 6 3
integral
1
b = a % 2; a%2
c = a / 2; remainder
• Relational Operators:
e1 e2 Result = e1 || e2 e1 e2 Result = e1 || e2
0 0 0 false false false
0 1 1 false true true
1 0 1 true false true
1 1 1 true true true
! - Logical NOT
• Reverse the meaning of a condition
• Example: if (!(radius > 90))
– Means if radius not bigger than 90.
• Usually:
– &: set OFF one bit
– |: set ON one bit
– ^: reverse one bit
Conditional Operator
• The conditional operator (?:) is used to simplify an
if/else statement
– Condition ? Expression1 : Expression2;
• sizeof variable_Identifier;
• sizeof (variable_Identifier);
• sizeof (Data_Taype);
• Example:
– int x;
– printf("size of x = %d", sizeof x);
– printf("size of long long = %d", sizeof(long long));
– printf("size of x = %d", sizeof (x));
Type Casting
• Explicit Type cast: carried out by programmer using casting
int k, i = 7;
float f = 10.14;
char c = 'B';
k = (i + f) % 3; // error
k = (int)(i + f) % 3;
NO YES NO YES
x < y?
Process A Process B
Decision Structure
• The flowchart segment below shows how a
decision structure is expressed in C as an
if/else statement
NO YES
if (x < y)
x < y?
a = x * 2;
else
Calculate a as Calculate a as
x plus y. x times 2. a = x + y;
Decision Structure
• The flowchart segment below shows a
decision structure with only one action to
perform
NO YES
x < y? if (x < y)
a = x * 2;
Calculate a
as x times 2.
Combining Structures
NO YES
x > min?
if (x > min)
{
Display “x is outside NO YES
the limits.”
x < max?
if (x < max)
printf("x is within the limits");
else
printf("x is outside the limits"); Display “x is outside Display “x is
the limits.” within limits.”
}
else
printf("x is outside the limits");
Example
if (x < 0.25)
if (x < 0)
count1++;
sign = -1;
else if (x >= 0.25 && x < 0.5)
else if (x == 0)
count2++;
sign = 0;
else if (x >= 0.5 && x < 0.75)
else
count3++;
sign = 1;
else
count4++;
Case Structure
• One of several possible actions is taken,
depending on the contents of a variable
Case Structure
• indicates actions to perform depending on the
value in years_employed
If years_employed = 2, If years_employed = 3,
bonus is set to 200 bonus is set to 400
If years_employed = 1, If years_employed is
CASE
bonus is set to 100 years_employed any other value, bonus
is set to 800
1 2 3 Other
YES
x < y? Process A
Repetition Structure
• The flowchart segment below shows a
repetition structure expressed in C as a while
loop
while (x < y)
YES x++;
x < y? Add 1 to x
While
while (loop_repetition_condition)
statement;
OR
//Compound statement
while (loop_repetition_condition)
{
statement1;
statement2; // …
}
Controlling a Repetition Structure
• The action performed by a repetition structure
must eventually cause the loop to terminate.
Otherwise, an infinite loop is created
YES
• How can this flowchart x < y? Display x
be modified so it is no
longer an infinite loop?
Controlling a Repetition Structure
• Adding an action within the repetition that
changes the value of x
YES
x < y? Display x Add 1 to x
A Pre-Test Repetition Structure
• This type of structure is known as a pre-test
repetition structure. The condition is tested
BEFORE any actions are performed
– if the condition does not exist, the loop will never
begin
YES
x < y? Display x Add 1 to x
Example
int counter = 0;
while (1);
while (counter < 1000) ;
C programming language
Display x
do
Add 1 to x
{
printf(…);
x++; YES
} while (x < y); x < y?
do-while
do
statement;
while (loop_repetition_condition)
OR
do //Compound statement
{
statement1;
statement2; // …
}
while (loop_repetition_condition)
For
OR
// Compound statement
for (initial_value ; condition;
update_counter) {
statement;
statement; // …
}
Array
• Generic declaration:
typename variablename[size];
– typename is any type
– variablename is any legal variable name
– size is a number the compiler can figure out
– For example : int a[10];
– Defines an array of ints with subscripts ranging from 0 to 9
– There are 10*sizeof(int) bytes of memory reserved for this array.
9 8 7 6 5 4 3 2 1 0
10 a
array[0] = 3;
array[2] = 4;
array[10] = 5;
No bounds checking!
array[-1] = 6;
sizeof(A)? 3 * 4 = 12
sizeof(A[0]) = sizeof(A[1]) = sizeof(A[2])? 4
Using Constants to Define Arrays
• It is useful to define arrays using constants:
#define MONTHS 12
float a [MONTHS];
• For example:
– int a [4] [3] ;
• 2-dimensional array
• 4 * 3 * sizeof(int)
– int a[4][3][2]
• 3-dimention array
• 4 * 3 * 2 * sizeof(int)
Multidimensional Arrays Representation
0 1
4 3
Examples
int a[10]; // Ok
• It’s the string terminator (not the size of the array) that
determines the length of the string
Accessing Individual Characters
• The first element of any array in C is at index 0. The
second is at index 1, and so on ...
char s[10];
s[0] = 'h';
s[1] = 'i’; ? ? ? ? ? ? 0\ ! i h
Developer
int x; ? 22F53
Compiler
00
int *p; 22F54 p
Don’t 02 22F55
scanf("%d", p); /* */ 2F 22F56
p = &x; 50 22F57
…
scanf("%d", p); /* Correct */
}
Using Pointers
• You can use pointers to access the values of other variables, i.e. the
contents of the memory for other variables
– int *q = NULL;
Generic Pointers: void *
• void *: a pointer to anything
int a, b;
int *p = &a, *q = &b;
p = p + q ; // Error
p = p * q; // Error
p = p / q; // Error
p = p - q; // OK
p = p + 3;
p += 1.6; // Error
p %= q; // Error
Arithmetic Operations
• When an integer is added to or subtracted
from a pointer, the new pointer value is
changed by the integer times the number of
bytes in the data variable the pointer is
pointing to
p = &a[2]; ? [1]
? [2]
q = &a[5];
? [3]
i = q - p; /* i is 3*/ ? [4]
i = p - q; /* i is -3 */ ? [5]
a[2] = a[5] = 0; ? [6]
? [7]
i = *p - *q; // i = a[2] – a[5]
? [8]
if (p < q) ...; /* true */ ? [9]
if (p == q)...; /* false */
if (p != q) ...; /* true */
Pointers and Arrays
\0 ! d l r o w , o l l e H
}
Multi-Dimensional Arrays
int a[row][col];
a[row][col] *(*(a + row) + col)
scanf(" %d ", &a[0][0]) scanf(" %d ", a[0])
a[row][col] *(a[row] + col)
&a[row][col] a[row] + col printf (" %d ", a[0][0]) printf(" %d ", *a[0])
a a[0][0] a[0]
scanf(" %d ", &a[2][2]) scanf(" %d ", a[2]+ 2)
a[0] + 2
printf (" %d ", a[2][2]) printf(" %d ", *(a[2] + 2))
[0][9] [0][8] [0][7] [0][6] [0][5] [0][4] [0][3] [0][2] [0][1] [0][0] a[0]
[1][9] [1][8] [1][7] [1][6] [1][5] [1][4] [1][3] [1][2] [1][1] [1][0] a[1]
[2][9] [2][8] [2][7] [2][6] [2][5] [2][4] [2][3] [2][2] [2][1] [2][0] a[2]
[3][9] [3][8] [3][7] [3][6] [3][5] [3][4] [3][3] [3][2] [3][1] [3][0] a[3]
[4][9] [4][8] [4][7] [4][6] [4][5] [4][4] [4][3] [4][2] [4][1] [4][0] a[4]
Array of Pointers
char *suit[ 4 ] = { "Hearts", "Diamonds", "Clubs",
"Spades" };
\0 s t r a e H suit[0]
\0 s d n o m a i D suit[1]
\0 s b u l C suit[2]
\0 s e d a p S suit[3]
Array of Pointers
int a=1, b=2, c=3, d=4; * &
int *k[4] = {&a, &b, &c, &d}; k[0]
k[1]
k[2]
k[3]
1 a k[0] 1 a
2 b k[1] 2 b
3 c k[2] 3 c
4 d k[3] 4 d
printf("%d %d %d %d", *k[0], *k[1],*k[2],*k[3]);
Functions
• Every C program starts with main() function
int main()
{
• Functions could be }
…
int main(void)
{
int a, b;
double c;
char d;
…
Calc(a, c, d, b); Function Call
return (0);
}
Functions that do not return a value
• Use the return type of void
– void functionName( DataType arg_1,…)
– void functionName()
– void functionName( void)
Function Call – An Example
1
#include <stdio.h> void fn1(void)
{
//function prototype local variable declaration;
//global variable declaration statements;
2 }
int main(void) 3
void fn2(void)
{
{
local variable declaration; local variable declaration;
statements; statements;
fn1( ); return;
4
fn2( ); }
return (0);
}
Call by value And Call by reference
• Call by value
– In all the examples that we have seen so far, this is the method that
has been used
• Call by reference
void main()
{
int x[10];
ReOrder(x); // ReOrder(&x);
}
void ReOrder(int *x)
{
int i, j, t;
for(i = 0; i < 9; i++)
for(j = i + 1; i < 10; ++j)
if(x[i] < x[j])
{
t = x[i]; x[i] = x[j]; x[j] = t;
}
}
Organizing Multi-File Programs
• A large C program should be divided into multiple files
// main.c // math.c
#include <stdio.h> double mathVar;
void Test() double sin()
{ {
// … double tempSin;
} // …
int main() return tempSin;
{ }
// …
return 0;
}
Identifiers and Scope
• Identifier
– The name of a variable, function, label, etc.
• int my_var1; /* a variable */
• pow_table(); /* a function */
• start: /* a label */
• Question:
– Does it make a difference where in a program an
identifier is declared?
YES! --> concept of ‘scope’
Scope of Identifiers
• Scope of a declaration of an identifier
– The region of the program that the declaration is
active (i.e., can access the variable, function, label,
etc.)
#include <stdio.h>
• File scope static int a = 10;
double product(double x, double y);
– Keyword static int main()
• Makes variable a ‘visible’ {
only within this source file double var1 = 3.0, var2 = 5.0;
double ans;
– Use file scope to avoid ans = product(var1, var2);
naming conflict if multiple // …
}
source files are used /* function definition */
double product(double x, double y)
{
double result;
result = x * y;
return result;
}
An Example
// File name: main.c
#include <stdio.h>
static int a = 10;
// File name: ExternFile.c /* function definition */
double product(double x, double y)
extern int a = 10;
{
/* function definition */ double result;
void TestExtern() // …
{ a = 70;
// … return result;
a = 90; }
// …
} int main()
{
a = 80;
}
Scope of Identifiers - Function Prototype Scope
#include <stdio.h>
• Function prototype scope double product(double x, double y);
– Identifiers x and y are not
int main()
visible outside the prototype {
int a = 10;
– Thus, names in the prototype double var1 = 3.0, var2 = 5.0;
do not have to match names in double ans;
the function definition ans = product(var1, var2);
• MUST match types, however! printf("var1 = %.2f\n"
"var2 = %.2f\n",var1,var2);
printf("var1*var2 = %g\n", ans);
}
/* function definition */
double product(double A, double B)
{
double result;
result = A * B;
return result;
}
Scope of Identifiers - Function Scope
• Function scope
– Active from the beginning to the end of a function
#include <stdio.h>
int main()
{
int a;
// …
return 0;
}
int FunctionScopeTest()
{
int b;
// …
return 0;
}
Scope of Identifiers - Block Scope
void main()
{ a = 10
a = 80;
f1(); a = 80
}
Storage Classes
• Refers to the lifetime of a variable
}
void auto_example(void)
{
auto int num = 1;
printf(" %d\n",num);
num = num + 2;
}
Static - Example
#include <stdio.h>
void auto_example(void);
int main(void)
{
int i;
printf("Static example:\n");
static_example( );
static_example( );
Static example:
static_example( ); 1
return(0); 3
} 5
Press any key to continue
void static_example(void)
{
static int num = 1;
printf(" %d\n",num);
num = num + 2;
}
Recursion
• Recursion is a technique that solves a problem by solving a smaller problem of
the same type
if (stopping case)
solve it
else
reduce the problem using recursion
Recursion solution of xy
#include <stdio.h>
double XpowerY(double, int);
int main(void)
{
double power, x; int y;
printf("Enter the value of x and y:\n");
scanf("%lf%d", &x, &y);
power = XpowerY(x, y);
printf("%.2f to the power of %d is %.2f\n\n", x, y, power);
return(0);
} Enter the value of x and y:
2
double XpowerY(double x, int y) 3
{ 2.00 to the power of 3 is 8.00
Press any key to continue
if (y ==1)
return x;
else
return x * XpowerY(x, y-1);
}
Recursive Steps of xy
#include <stdio.h>
double XpowerY(double, int); ;x = 2; y = 2
int main(void)
2 ;return x
{
double power, x; int y;
printf("Enter the value of x and y:\n");
;x = 2; y = 2
scanf("%lf%d", &x, &y);
power = XpowerY(x, y); 2*2 x * XpowerY(2, 1)
printf("%.2f to the power of %d is %.2f\n\n", x, y, power);
return(0);
} ;x = 2; y = 3
double XpowerY(double x, int y) 2*4 x * XpowerY(2, 2)
{
if (y ==1)
return x;
;x = 2; y = 4
else
2*8 x * XpowerY(2, 3)
return x * XpowerY(x, y-1);
}
Pointer to Function
#include <stdio.h>
void f1(float a){ printf("F1 %g", a);} A function pointer is defined in
void f2(float a){ printf("F2 %g", a);} the same way as a function
prototype, but the function
name is replaced by the pointer
int main(){ name prefixed with an asterisk
and encapsulated with
void (*ptrF)(float a); parenthesis
ptrF = f1; Example:
int (*fptr)(int, char)
ptrF(12.5);
fptr = some_function;
ptrF = f2;
ptrF(12.5); (*ftpr)(3,'A');
some_function(3,'A');
getch();
return 0;
}
Array of Functions
#include<stdio.h>
Key
previously allocated
int *ptr;
ptr = (int *)malloc(sizeof(int)); // new allocation new allocation
10
Memory ptr
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
free
• Prototype: void free(void *ptr)
– releases the area pointed to by ptr #include <stdlib.h>
– ptr must not be null
• trying to free the same area twice will generate an error
2
5
p2
p1
initial memory
0 1 2 3 4 5 6 7
2 NULL Key
free(p1); p1
p2 allocated memory
after free free memory
0 1 2 3 4 5 6 7
Allocating Memory for a Pointer
• There is another way to allocate memory so the pointer can
point to something:
#include <stdio.h>
#include <stdlib.h>
int main(){
int *p;
p = (int *) malloc( sizeof(int) ); /* Allocate 4 bytes */
scanf("%d", p);
printf("%d", *p);
// ....
free(p); /* This returns the memory to the system*/
/* Important !!! */
}
Allocating Memory for a Pointer
• You can use malloc and free to dynamically
allocate and release the memory
int *p;
p = (int *) malloc(1000 * sizeof(int) );
for(i=0; i<1000; i++)
p[i] = i;
p[999]=3;
p[1000]=3; /* Wrong! */
free(p);
p[0]=5; /* Wrong! */
Structures
• Structures
– Be able to use compound data structures in programs
• Unions
– Be able to share storage space of their members
• Enumerations
– Be able to use compound symbolic constants
User Defined Data Types (typedef)
• The C language provides a facility called typedef for creating
synonyms for previously defined data type names.
• For example, the declaration:
typedef int Length;
makes the name Length a synonym (or alias) for the data type int.
• The data type name Length can now be used in declarations in
exactly the same way that the data type int can be used:
Length a, b, len ;
Length numbers[10] ;
typedef char String[50];
typedef int Array[10];
String name;
Array ages;
Structures (struct)
• Structures—sometimes referred to as aggregates—are collections
of related variables under one name
struct
{
char firstName[ 20 ];
char lastName[ 20 ];
int age;
char gender;
double hourlySalary;
} Ali;
id amount num_avail
cost
• Here, the system uses 4-byte alignment of integers, so amount and num_avail
must be aligned Four bytes wasted for each structure!
Memory layout
struct COST {
int amount;
char currency_type[2];
}
struct PART {
struct COST cost;
char id[2];
int num_avail; currency_type
}
amount id num_avail
cost
• Implementation dependent!!!
Accessing Struct Members
• Individual members of a struct variable may be accessed using
the structure member operator (the dot, "."):
struct employee
myEmp.firstName ; {
employee. firstName; // Error char firstName[ 20 ];
// …
} myEmp;
person
age LastName FirstName
gpa id
20 9140153 14 Jafarinezhad omid students[0]
20 2222222 90 Shekarestani Samad Students[1]
20 11111111 100 Shekarestani Khaje Nezam students[2]
students[3]
Pointers to Structures
return (d);
}
Date today;
void foo(void)
{ 0x1008 today.year: 2008
Date today;
0x1004 today.day: 4
create_date2(&today, 9, 4, 2008);
} 0x1000 today.month: 9
Compression of Structures
• Structures may not be compared using
operators == and !=, because structure
members are not necessarily stored in
consecutive bytes of memory
struct a {
int a; // OK
int b;
};
struct a b, c;
b.a = 10;
b.b = 30;
c = b;
if(c == b) // Error
Enumeration
• Enumeration is a user-defined data type. It is defined using the
keyword enum and the syntax is:
enum tag_name {name_0, …, name_n} ;
• The tag_name is not used directly. The names in the braces are
symbolic constants that take on integer values from zero through n.
As an example, the statement:
enum colors { red, yellow, green } ;
– creates three constants. red is assigned the value 0, yellow is assigned 1 and
green is assigned 2
Enumeration
• Values in an enum start with 0, unless specified otherwise, and are
incremented by 1
• Only one member, and thus one data type, can be referenced at
a time
Unions representation
c
union myDataUnion {
int i;
char c;
float f;
i
} u1, u2;
union myDataUnion u3;
f
u1.i = 4;
u1.c = ’a’;
u2.i = 0xDEADBEEF;
Unions
• The operations that can be performed on a
union are the following:
– assigning a union to another union of the same type
– taking the address (&) of a union variable
– accessing union members using the structure
member operator and the structure pointer operator
union a
{
int a; // OK
char b[4];
};
union a b = {10};
printf("%d", b.a);
Unions
union AnElt {
int i;
?
char c; How should your program keep track whether
} elt1, elt2; elt1, elt2 hold an int or a char?
elt1.i = 4;
elt2.c = ’a’;
?
elt2.i = 0xDEADBEEF; Basic answer: Another variable holds that info
unsigned : 19;
unsigned b : 4;
};
• uses an unnamed 19-bit field as padding—nothing can be stored in those 19
bits
• An unnamed bit field with a zero width is used to align the next bit field on
a new storage-unit boundary
• For example, the structure definition
struct example {
unsigned a : 13;
unsigned : 0;
unsigned b : 4;
};
uses an unnamed 0-bit field to skip the remaining bits (as many as there
are) of the storage unit in which a is stored and to align b on the next
storage-unit boundary
An Example - disk drive controller
• Frequently device controllers (e.g. disk drives)
and the operating system need to
communicate at a low level. Device controllers
contain several registers which may be packed
together in one integer
An Example - disk drive controller
struct DISK_REGISTER {
unsigned ready:1;
unsigned error_occured:1;
unsigned disk_spinning:1;
unsigned write_protect:1;
unsigned head_loaded:1;
unsigned error_code:8;
unsigned track:9;
unsigned sector:5;
unsigned command:5;
};
struct DISK_REGISTER *disk_reg = (struct DISK_REGISTER *) DISK_REGISTER_MEMORY;
/* Define sector and track to start read */
disk_reg->sector = new_sector;
disk_reg->track = new_track;
disk_reg->command = READ;
/* wait until operation done, ready will be true */
while ( ! disk_reg->ready ) ;
/* check for errors */
if (disk_reg->error_occured)
{ /* interrogate disk_reg->error_code for error type */
switch (disk_reg->error_code)
......
}