Week 5 A Brief Intro to C Language EE302 Intro. To Embedded Systems 1 Disclaimer • Most of the slides used for this lecture are based on Bjarne Stroustrup’s Programming: Principles and Practice using C++. – www.stroustrup.com/Programming • Few slides have been modified/updated EE302: Week 5 - A Brief Intro to C Language 2 2 Why are we using C? • Using C instead of Java (or Python, or your other favorite language)? • C is the de facto standard for embedded systems because of: – Precise control over what the processor is doing • Provide direct access to low level hardware API's – Availability of C-compiler for embedded devices which is not true for any high-level language – Modest requirements for ROM, RAM, and MIPS, so much cheaper system • C (the runtime and the generated executable) is small. A bunch of stuff is not required to be loaded into the system to get the code running – Predictable behavior, deterministic resource usage, no garbage collection EE302: Week 5 - A Brief Intro to C Language 3 3 DR standing with Ken Thompson in the 1973 photo above ”C is a strongly typed, weakly checked, programming language.” –Dennis Ritchie Creator of C, and co-creator of UNIX EE302: Week 5 - A Brief Intro to C Language 4 4 C is C++’s closest Modern C and C++ are siblings relative, and compatible in many areas, so much of your C++ knowledge 2011 C++11 C11 carries over C++14 2017/2018 C++17 C18 C++20 EE302: Week 5 - A Brief Intro to C Language 5 5 "Fortune favors the prepared mind.” –Louis Pasteur Data types, variables, operators C BASICS EE302: Week 5 - A Brief Intro to C Language 6 6 Hello World - 1 // A Hello World program #include <stdio.h > int main(void) { printf("hello, world!\n"); return 0; } EE302: Week 5 - A Brief Intro to C Language 7 7 Hello World - 2 • • • • Call flow of hello world Role of main() function Role of header file Typical errors which can be made in this small program EE302: Week 5 - A Brief Intro to C Language 8 8 Values and Statements • A statement is a unit of code that does something – a basic building block of a program. • An expression is a statement that has a value, for instance, – a number, – a string, – the sum of two numbers, etc. 4 + 2, x - 1, and – "hello, world!\n" are all expressions. • Not every statement is an expression e.g. – #include <stdio.h> EE302: Week 5 - A Brief Intro to C Language 9 9 Operators • Used to perform calculations • Act on expressions to form a new expression • Types – – – – – Mathematical Relational Logical Bitwise Conditional EE302: Week 5 - A Brief Intro to C Language 10 10 Data Types Built-in Data types • Character types (such as char) • Integer types (such as int) • Floating-point types (such as double) User-defined Data types • Enumeration types for representing specific sets of values (enum) • Pointer types (such as int *) • Array types (such as char[]) • Structures void • used to signify the absence of type information EE302: Week 5 - A Brief Intro to C Language 11 11 Basic C Variable Types What is the largest signed integer that may be stored in 20 bits? EE302: Week 5 - A Brief Intro to C Language 12 12 Unsigned Integer Types What is the largest unsigned integer that may be stored in 20 bits? EE302: Week 5 - A Brief Intro to C Language 13 13 Static Typing • C is a statically typed language, which means that types are checked at compile time. • The process by which types are checked is referred to as type checking – the type of an object constrains the operations that the object can perform. • In C, the compiler checks whether the operations we write are supported by the types we use. – If we try to do things that the type does not support, the compiler generates an error message and does not produce an executable file. • As programs get more complicated, static type checking can help find bugs • A consequence of static checking is that the type of every entity we use must be known to the compiler. – As one example, we must declare the type of a variable before we can use that variable. EE302: Week 5 - A Brief Intro to C Language 14 14 Advice: Deciding which Type to Use 1. Use an unsigned type when you know that the values cannot be negative 2. Use int for integer arithmetic. short is usually too small and, in practice, long often has the same size as int. If your data values are larger than the minimum guaranteed size of an int, then use long long 3. Do not use plain char in arithmetic expressions. Use them only to hold characters or truth values. Computations using char are especially problematic because char is signed on some machines and unsigned on others. If you need a tiny integer, explicitly specify either signed char or unsigned char 4. Use double for floating-point computations; float usually does not have enough precision, and the cost of double-precision calculations versus single-precision is negligible. In fact, on some machines, double-precision operations are faster than single. The precision offered by long double usually is unnecessary and often entails considerable run-time cost EE302: Week 5 - A Brief Intro to C Language 15 15 Variables • Nothing of interest can be done with a computer without storing data in memory • The places in which we store data are called objects • To access an object, we need a name • A named object is called a variable and has a specific type (such as int or char) that determines what can be put into the object and which operations can be applied • The data items we put into variables are called values • A statement which introduces a variable’s name into a program and specifies its type (such as int) is called declaration • However, if a declaration also sets aside memory for the variable (by providing an initial value), it is also called a definition EE302: Week 5 - A Brief Intro to C Language 16 16 Example char c = 'c'; // c is 'c' i.e., 0x63 int i = 1; // i has value 1 i = 3.14; // i has value 3 double pi = i; // pi has value 3.0 unsigned char c = -1; // assuming 8-bit chars, c has value 255 signed char c2 = 256; // assuming 8-bit chars, the value of is undefined or 0 in little endian c2 EE302: Week 5 - A Brief Intro to C Language 17 17 Printable ASCII Codes 0 1 2 3 ! " # 4 5 6 7 8 9 A B C D E F $ % & ' ( ) * + , - . / 3 0 1 2 3 4 5 6 7 8 9 : ; < = > ? 4 @ A B C D E F G H I J K L M N O 5 P Q R S T U V W X Y Z [ \ ] ^ _ 6 ` a b c d e f g h i j k l m n o 7 p q r s t u v w x y z { | } ~ 2 space ❖ Examples: ASCII code for space character = 20 (hex) = 32 (decimal) ASCII code for 'L' = 4C (hex) = 76 (decimal) ASCII code for 'a' = 61 (hex) = 97 (decimal) 18 DEL ASCII Table EE302: Week 5 - A Brief Intro to C Language 19 19 char as ASCII and as Integer char c = 'A'; char d = 65; // ASCII code of 'A' printf("%c\t%c\n", c, d); // A A printf("%d\t%d\n", c, d); // 65 65 int i = 65; printf("%d\t%c\n", i, i); // 65 A EE302: Week 5 - A Brief Intro to C Language 20 20 Operators • Discussion will focus on; – Unary Operators • ++ (arithmetic perspective) • -- (arithmetic perspective) • ! (logical perspective) etc – Binary Operators • Arithmetic – +, -, *, /, % • Relational – >, <. >=, <=, ==, != • Logical – &&, || • Review of operators http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B EE302: Week 5 - A Brief Intro to C Language 21 21 Increment ++, Decrement -• Provide a convenient notational shorthand for adding or subtracting 1 from an object. • There are two forms of these operators: prefix and postfix • Prefix form increments (or decrements) its operand and yields the changed object as its result • The postfix operators increment (or decrement) the operand but yields a copy of the original, unchanged value as its result: int i = 0, j; j = ++i; // j = ___ , i = ___: prefix yields the incremented value j = i++; // j = ___ , i = ___: postfix yields the unincremented value EE302: Week 5 - A Brief Intro to C Language 22 22 Arithmetic Operators int i = 1024; int k = -i; // k = ___ • Overflow/Underflow Issues in Integers short s_value = 32767; s_value += 1; unsigned short us_value = 0; us_value -= 1; EE302: Week 5 - A Brief Intro to C Language 23 23 Relational and Logical Operators • Non-zero integer is implicitly treated as true • Zero integer is implicitly treated as false EE302: Week 5 - A Brief Intro to C Language 24 24 "Programming is learned by writing programs.” -Brian Kernighan If/else, loops C FLOW CONTROL EE302: Week 5 - A Brief Intro to C Language 25 25 Selection / Conditional Statements • • • • • • if (1) {} if (7) {} int a = 1; if (a--) {} if …. else … Nested if-else Simple and complex condition checking in if arguments T F Condition action_if EE302: Week 5 - A Brief Intro to C Language 26 action_else 26 Switch statement and its technicalities • • If you have a large decision tree, and all the decisions depend on the value of the same variable, you will probably want to consider a switch statement instead of a ladder of if...else or else if constructions The value on which we switch must be of an integer, char, or enumeration type. Evaluate == const1? – In particular, you cannot switch on a string. • The values in the case labels must be constant expressions. • • action1 F == const2? – In particular, you cannot use a variable in a case label. • T You cannot use the same value for two case labels. You can use several case labels for a single case. Don't forget to end each case with a break. T action2 F action3 – Unfortunately, the compiler won't warn you if you forget. EE302: Week 5 - A Brief Intro to C Language 27 27 while Loop while (condition) statement loop_body/ statement T condition F EE302: Week 5 - A Brief Intro to C Language 28 28 Loop Machine // calculate and print a table of squares 0 - 99 int main() { int i = 0;// start from 0 while (i < 100) { printf("%d\t%d\n", i, i*i); ++i; // increment i } } • A way to repeat some statement (to loop) • A variable to keep track of how many times we have been through the loop (a loop variable or a control variable) – here the int called i • An initializer for the loop variable • A termination criterion, – here, that we want to go through the loop 100 times • Something to do each time around the loop (the body of the loop) EE302: Week 5 - A Brief Intro to C Language 29 29 for Loop for( for-init-statement; conditionOPT ; expressionOPT ) statement init_statement loop_body / statement expressionOPT T conditionOPT F EE302: Week 5 - A Brief Intro to C Language 30 30 Loops – Iterative Statements (contd.) • Nested loops • break statement • continue statement EE302: Week 5 - A Brief Intro to C Language 31 31 " No amount of genius can overcome obsession with detail.” - Traditional FUNCTIONS EE302: Week 5 - A Brief Intro to C Language 32 32 Functions • A function is a named sequence of statements • A function can return a result (also called a return value) • Functions – – – – – Definition Parameter Body Return Type Prototype EE302: Week 5 - A Brief Intro to C Language 33 33 Recap: Why functions? • Chop a program into manageable pieces – “divide and conquer” • Match our understanding of the problem domain – Name logical operations – A function should do one thing well • Functions make the program easier to read • A function can be useful in many places in a program • Ease testing, distribution of labor, and maintenance • Keep functions small – Easier to understand, specify, and debug EE302: Week 5 - A Brief Intro to C Language 34 34 Functions • Our function int square(int x) { return x * x; } is an example of Return_type function_name(Parameter list) // (type name, etc.) { // use each parameter in code return some_value;// of Return_type } EE302: Week 5 - A Brief Intro to C Language 35 35 Another Example • Earlier we looked at code to find the larger of two values. Here is a function that compares the two values and returns the larger value. int max(int a, int b) { if (a < b) return b; else return a; } int x = max(7, 9); int y = max(19, -27); int z = max(20, 20); // this function takes 2 parameters // x becomes 9 // y becomes 19 // z becomes 20 EE302: Week 5 - A Brief Intro to C Language 36 36 Functions in C • There can be only one function of a given name • Function argument type checking is optional – Use a compiler option that makes it compulsory • There are no references (and therefore no pass-by-reference) – pass a pointer • There are no member functions • There is an alternative function definition syntax EE302: Week 5 - A Brief Intro to C Language 37 37 Function prototypes in C (function argument checking is optional) /* avoid these mistakes – use a compiler option that enforces C++ rules */ int g(int); int h(); // prototype – like C++ function declaration // not a prototype – the argument types are unspecified int f(p, b) char* p; char b;// old-style definition – not a prototype { /* … */ } int my_fct(int a, double d, char* p)// new-style definition – a prototype { f(); // ok by the compiler! But gives wrong/unexpected results f(d, p); // ok by the compiler! But gives wrong/unexpected results h(d); // ok by the compiler! But may give wrong/unexpected results ff(d); // ok by the compiler! But may give wrong/unexpected results g(p); g(); // error: wrong type // error: argument missing } EE302: Week 5 - A Brief Intro to C Language 38 38 “The best is the enemy of the good. -Voltaire Numbers, 2’s Complement, ASCII, Operators SOME SIDE INFO EE302: Week 5 - A Brief Intro to C Language 39 39 Declarations • • • • • A declaration introduces a name into a scope. A declaration also specifies a type for the named object. Sometimes a declaration includes an initializer. A name must be declared before it can be used in a C++ program. Examples: int x = max(7, 9); // x becomes 9 int y = max(19, -27);// y becomes 19 int z = max(20, 20);// z becomes 20 int a = 7; // an int variable named ‘a’ is declared const double cd = 8.7;// a double-precision floating-point constant double sqrt(double); // a function taking a double argument // and returning a double result EE302: Week 5 - A Brief Intro to C Language 40 40 Declarations • Declarations are frequently introduced into a program through "headers" – A header is a file containing declarations providing an interface to other parts of a program • This allows for abstraction – you don’t have to know the details of a function like printf() in order to use it. When you add #include "stdio.h" to your code, the declarations in the file stdio.h become available (including printf, etc.). EE302: Week 5 - A Brief Intro to C Language 41 41 For example • Define your own functions and variables: #include "stdio.h" // we find the declaration of printf in here int f(int x) { /* … */ } // declaration of f int main() { int i = 7; // declaration of i printf("% d\n", f(i)); } EE302: Week 5 - A Brief Intro to C Language 42 42 Definitions • A declaration that (also) fully specifies the entity declared is called a definition – Examples int a; int b = 7; // an (uninitialized) int double sqrt(double) { … }; // a function with a body struct Point { int x; int y; }; • Examples of declarations that are not definitions double sqrt(double);// function body missing struct Point; // class members specified elsewhere extern int a; // extern means “not definition” // “extern” is archaic; we will hardly use it EE302: Week 5 - A Brief Intro to C Language 43 43 Declarations and definitions • You can’t define something twice – A definition says what something is – Examples int a;// definition int a;// error: double definition double sqrt(double d) { … }// definition double sqrt(double d) { … }// error: double definition • You can declare something twice – A declaration says how something can be used int a = 7; extern int a; double sqrt(double); double sqrt(double d) { // definition (also a declaration) // declaration // declaration … }// definition (also a declaration) EE302: Week 5 - A Brief Intro to C Language 44 44 Why both declarations and definitions? • To refer to something, we need (only) its declaration • Often, we want the definition “elsewhere” – Later in a file – In another file • preferably written by someone else • Declarations are used to specify interfaces – To your own code – To libraries • Libraries are key: we can’t write all ourselves, and wouldn’t want to • In larger programs – Place all declarations in header files to ease sharing EE302: Week 5 - A Brief Intro to C Language 45 45 Header Files and the Preprocessor • A header is a file that holds declarations of functions, types, constants, and other program components. • The construct #include "stdio.h" is a “preprocessor directive” that adds declarations to your program – Typically, the header file is simply a text (source code) file • A header gives you access to functions, types, etc. that you want to use in your programs. – Usually, you don’t really care about how they are written. – The actual functions, types, etc. are defined in other source code files • Often as part of libraries EE302: Week 5 - A Brief Intro to C Language 46 46 Source files // declarations: token.h: struct Token { … }; struct Token_stream { … }; extern Token_stream ts; token.c: … use.c: #include "token.h" … Token t = ts.year; … #include "token.h" //definitions: Token_stream ts; … • • A header file (here, token.h) defines an interface between user code and implementation code (usually in a library) The same #include declarations in both .c files (definitions and uses) ease consistency checking EE302: Week 5 - A Brief Intro to C Language 47 47 Scope • A scope is a region of program text – Global scope (outside any language construct) – Local scope (between { … } braces) – Statement scope (e.g., in a for-statement) • A name in a scope can be seen from within its scope and within scopes nested within that scope – Only after the declaration of the name (“can’t look ahead” rule) – Class members can be used within the class before they are declared • A scope keeps “things” local – Prevents my variables, functions, etc., from interfering with yours – Remember: real programs have many thousands of entities – Locality is good! • Keep names as local as possible EE302: Week 5 - A Brief Intro to C Language 48 48 Scopes nest int x; // global variable – avoid those where you can int y; // another global variable int f() { int x; // local variable (Note – now there are two x’s) x = 7; // local x, not the global x { int x = y;// another local x, initialized by the global y // (Now there are three x’s) ++x; // increment the local x in this scope } } // avoid such complicated nesting and hiding: keep it simple! EE302: Week 5 - A Brief Intro to C Language 49 49 Preprocessing Directives • #include • #define #define LENGTH_IN_METERS (5) • Macros #define #define #define TESTBIT(var, bit) SETBIT(var, bit) CLRBIT(var, bit) ((var) & (1 <<(bit))) ((var) |= (1 << (bit))) ((var) &= ~(1 << (bit))) EE302: Week 5 - A Brief Intro to C Language 50 50 Conditional Compilation • • • • #if #endif #ifdef #ifndef #ifdef __cplusplus // in C++ #else /* in C */ #endif EE302: Week 5 - A Brief Intro to C Language 51 51 Miscellaneous • sizeof Operator EE302: Week 5 - A Brief Intro to C Language 52 52 Type Aliasing by typedef Keyword • A declaration prefixed by the keyword typedef declares a new name for the type rather than a new variable of the given type typedef double gpa; typedef char ascii; typedef int int32; typedef short int16; EE302: Week 5 - A Brief Intro to C Language 53 53 const Qualifier • Specifies that a variable's value is constant and tells the compiler to prevent the programmer from modifying it // constant_values1.c int main() { const int max = 5; const int x;// const not initialized: OK in C (error in C++) int a1[max];// error: array bound not a constant (max is not a const) int a2[x]; // error: array bound not a constant (here you see why) } • In C++, you can use the const keyword instead of the #define preprocessor directive to define constant values – But not in C. In C, a const is never a compile-time constant • Values defined with const are subject to type checking, and can be used in place of constant expressions EE302: Week 5 - A Brief Intro to C Language 54 54 L-values, R-values • L-value is short for “left hand side value” (of an assignment) • int var • float x • Examples of non-lvalue expressions: • 3+3 • "str" • const int i = 3 • R-value is short for “right hand side value” because rvalues can appear on the right hand side of an assignment. Anything with a well-defined value can be an rvalue, including an assignment: (x = 5) can be used as an rvalue whose value is 5, e.g. y = (x=5); • When we use an object as an rvalue, normally we use the object’s value (its contents) • When we use an object as an lvalue, normally we use the object’s identity (its location in memory) EE302: Week 5 - A Brief Intro to C Language 55 55 Missing in C (from a C++ perspective) • Classes and member functions • Derived classes and virtual functions – Use struct and global functions – Use struct, global functions, and pointers to functions – You can do OOP in C, but not cleanly, and why would you want to? – You can do GP in C, but why would you want to? • Templates and inline functions • Exceptions • Function overloading • new/delete • References • const in constant expressions – Use macros – Use error-codes, error-return values, etc. – Give each function a separate name – Use malloc()/free() – Use pointers – Use macros EE302: Week 5 - A Brief Intro to C Language 56 56 Missing in C (from a C++ perspective) • With no classes, templates, and exceptions, C can’t provide most C++ standard library facilities – Containers • vector, map, set, string, etc. • Use arrays and pointers • Use macros (rather than parameterization with types) – STL algorithms • • • • sort(), find(), copy(), … Not many alternatives use qsort() where you can Write your own, use 3rd party libraries – I/O streams • Use stdio: printf(), getch(), etc. – Regular expression • Use a 3rd party library EE302: Week 5 - A Brief Intro to C Language 57 57 Standard function libraries • • • • • <stdio.h> <string.h> <ctype.c> <stdlib.h> <math.h> printf(), scanf(), etc. strcmp(), etc. isspace(), etc. malloc(), etc. sqrt(), etc. • Warning: By default, Microsoft tries to force you to use safer, but non-standard, alternatives to the unsafe C standard library functions EE302: Week 5 - A Brief Intro to C Language 58 58 “Caveat emptor!” –Good advice ARRAYS EE302: Week 5 - A Brief Intro to C Language 59 59 One-Dimensional Arrays • An element of an array is accessed using the array name and an index or subscript, for example: y[5] which can be used like a variable • In VC++, the subscripts always start with 0 and increment by 1, so y[5] is the sixth element • The name of the array is the address of the first element and the subscript is the offset y[0] y[1] y[2] … y[k-1] y[k] y[k+1] … y[98] y[99] EE302: Week 5 - A Brief Intro to C Language 60 60 Definition and Initialization • An array is defined using a declaration statement data_type array_name[size]; – – – – allocates memory for size elements subscript of first element is 0 subscript of last element is size-1 size must be a compile time constant EE302: Week 5 - A Brief Intro to C Language 61 61 Example #define L 5 int list[L]; list[0] list[1] list[2] list[3] • allocates memory for 5 integer variables list[4] • subscript of first element is 0 • subscript of last element is L-1 i.e., 4 • C/C ++ does not check bounds on arrays list[6] = 5; /* may give segmentation fault or overwrite other memory locations*/ EE302: Week 5 - A Brief Intro to C Language 62 62 Initializing Arrays • Arrays can be initialized at the time they are declared. • Examples: double taxrate[3] = { 0.15, 0.25, 0.3 }; char list[5] = { 'h', 'e', 'l', 'l', 'o' }; double vec[10] = { 0.0 }; //assigns zero to all 10 elements int s[] = { 5,0,-5 }; // the size of s is 3 EE302: Week 5 - A Brief Intro to C Language 63 63 Assigning values to an array For loops are often used to assign values to an array list[0] list[1] list[2] list[3] Example: list[4] #define L 5 int list[L], i; for (i = 0; i < L; i++) { list[i] = i; } EE302: Week 5 - A Brief Intro to C Language 64 0 1 2 3 4 list[0] list[1] list[2] list[3] list[4] 64 Function Arguments • Individual elements of an array can be passed as regular arguments. void donothing(int a, int b) { … } #define L 5 int main(void) { // Declare variables and functions int array[L] = { 1,2,3,4,5 }; donothing(array[2], array[4]); Calls donothing(3, 5); } EE302: Week 5 - A Brief Intro to C Language 65 65 Passing Arrays to Functions • Arrays are always pass by pointers – Modifications to the array are reflected to main program • The array name is the address of the first element • The maximum size of the array must be specified at the time the array is declared. • The actual number of array elements that are used will vary, so the actual size of the array is usually passed as another argument to the function EE302: Week 5 - A Brief Intro to C Language 66 66 Exercise int sum_arr(int b[], int n); int main() { #define L 2 int a[L] = { 3, 5 }; int c = sum_arr(a, L); } a[0]=3 a[1]=5 c=? 8 int sum_arr(int b[], int n) { int sum = 0, i; for (i = 0; i < n; i++) sum += b[i]; return(sum); } b= n=2 i=0 1 2 sum=0 3 8 EE302: Week 5 - A Brief Intro to C Language 67 67 Arrays and pointers • Defined almost exactly as in C++ • In C, you have to use them essentially all the time – because there is no vector, map, string, etc. • Remember – An array doesn’t know how long it is • it “decays” to a pointer – There is no array assignment • use memcpy() – A C-style string is a zero-terminated array of char EE302: Week 5 - A Brief Intro to C Language 68 68 C-style strings • In C a string (called a C-string or a C-style string in C++ literature) is a zero-terminated array of characters char* p = "asdf"; char s[] = "asdf"; 'a' p: s: 'a' 's' 's' 'd' 'd' 'f' 'f' 0 0 EE302: Week 5 - A Brief Intro to C Language 69 69 C-style strings • Comparing strings #include <string.h> if (s1 = = s2) { // do s1 and s2 point to the same array? // (typically not what you want) } if (strcmp(s1, s2) = = 0) { // do } s1 and s2 hold the same characters? • Finding the length of a string int lgt = strlen(s);// note: goes through the string at run time // looking for the terminating 0 • Copying strings strcpy(s1, s2); // copy characters from s2 into s1 // be sure that s1 can hold that many characters // and/or use strncpy EE302: Week 5 - A Brief Intro to C Language 70 70 C-style strings • The string copy function strcpy() is the archetypical C function (found in the ISO C standard library) • Unless you understand the implementation below, don’t claim to understand C: char* strcpy(char* p, const char* q) { while (*p++ = *q++); return p; } EE302: Week 5 - A Brief Intro to C Language 71 71 “Be careful what you wish for; you might get it.” -Traditional POINTERS EE302: Week 5 - A Brief Intro to C Language 72 72 Addresses and Pointers name address Memory - content .. .. int x1 = 1, x2 = 7; double dist = 4.23; x1 16 1 int *p; x2 20 7 dist 24 4.23 p 32 q 36 … ???? 36 8 int q = 8; p = &q; EE302: Week 5 - A Brief Intro to C Language 73 73 What is a Pointer? • A pointer is a variable that holds the address of a memory location • If a variable p holds the address of another variable q, then p is said to point to q • If q is a variable at location 40 in memory, then p would have the value 40 (q’s address) EE302: Week 5 - A Brief Intro to C Language 74 74 How to declare a pointer variable • Pointer variables are declared using an asterisk * before the pointer name int a, b, *ptr; • ptr is a pointer to a memory location that can store an integer EE302: Week 5 - A Brief Intro to C Language 75 75 Address Operator: & • A variable can be referenced using the address operator & • For the previous example: &x1 is the address of x1 printf("%d", &x1); // will print 16 (address) printf("%d", x1); // will print 1 (content) EE302: Week 5 - A Brief Intro to C Language 76 76 * has different meanings in different contexts • a = x * y; → multiplication • int *ptr; → declare a pointer • * is also used as indirection or de-referencing operator in C statements. • ptr = &y; • a = x * *ptr; EE302: Week 5 - A Brief Intro to C Language 77 77 Example: Pointers, address, indirection name int a, b; address memory .. int *c, *d; a 100 5 ? d = &b; b 104 9 ? *d = 9; c 108 ? 100 d 112 ? 104 a = 5; c = &a; printf("c = % d, *c = % d, &c = % d\n", c, *c, &c); c=100 *c=5 &c=108 printf("a = % d, b = % d\n", a, b); a=5 b=9 EE302: Week 5 - A Brief Intro to C Language 78 78 Exercise: Trace the following code int x, y; int *p1, *p2; name x = 3 + 4; address memory … y = x / 2 + 5; p1 = &y; x 512 ? *p1 = x + *p2; y 516 ? *p2 = *p1 + y; p1 520 ? printf("p1 = % d, *p1 = % d, &p1 = % d\n", p1, *p1 , &p1); p2 524 ? p2 = &x; printf("x = % d, &x = % d, y = % d, &y = % d\n", x, &x, y, &y); EE302: Week 5 - A Brief Intro to C Language 79 79 Declaring pointers • When using the form int *p, q; the * operator does not distribute • In the above example – p is declared to be a pointer to int. – q is declared to be an int. • If you want both to be pointer, then use the form int *p, *q; EE302: Week 5 - A Brief Intro to C Language 80 80 Assigning values to a pointer int a; int *iPtr; • Variables are not initialized in the above example • the assignment operator (=) is defined for pointers • As always, the right hand side can be any expression as long as it evaluates to the same type as the left • the operator & in front of an ordinary variable produces the address of that variable. a = 4 + 5; iPtr = &a; EE302: Week 5 - A Brief Intro to C Language 81 81 Exercise Give a memory snapshot after each set of assignment statements a 102 short a=1, b=2, *ptr; b 104 ptr = &b; ptr 106 a = *ptr; *ptr = 5; 110 EE302: Week 5 - A Brief Intro to C Language 82 82 NULL pointer • A pointer can be assigned or compared to the integer zero • A pointer variable whose value is 0 is not pointing to anything that can be accessed EE302: Week 5 - A Brief Intro to C Language 83 83 Pointer Initialization int *iPtr=0; char *s=0; double *dPtr=0; iPtr s dPtr !!! When we assign a value to a pointer during it is declaration, we mean to put that value into pointer variable (no indirection)!!! int *iPtr; is same as int *iPtr; iPtr=0; // not like *iPtr = 0; EE302: Week 5 - A Brief Intro to C Language 84 84 Dynamic Memory Allocation • Dynamic allocation can be used to create arrays at runtime • The malloc operator allocates a block of memory • The malloc operator returns a pointer to that block of memory double* p1 = (double*)malloc(sizeof(double));// allocate one double int* p = (int*)malloc(sizeof(int) * n);//allocate an array of n ints • When a pointer to a block of memory is assigned to a pointer variable, that variable effectively becomes an array EE302: Week 5 - A Brief Intro to C Language 85 85 Deleting Pointers • Memory that has been allocated with the malloc operator can be deallocated with the free operator • When memory is deallocated, you are releasing it so that it can be used again by your program • free does not deallocate a pointer variable, just the memory that it points to • Failure to delete allocated resources after you are done using them can lead to poor performance EE302: Week 5 - A Brief Intro to C Language 86 86 Free store: malloc()/free() #include <stdlib.h> void f(int n) { // malloc() takes a number of bytes as its argument // allocate an array of n ints int* p = (int*)malloc(sizeof(int) * n); /* … */ // free() returns memory allocated by malloc() to free store free(p); } EE302: Week 5 - A Brief Intro to C Language 87 87 Argument Passing in Functions • In C, function arguments are passed-by-value – except when an array name is used as an argument • An array name is the address of the first element • Values in an array can be modified by statements within a function • To modify a function argument, a pointer to the argument must be passed – scanf(“%d”, &x); This statement specifies that the value read is to be stored at the address of x • The actual parameter that corresponds to a pointer argument must be an address or pointer. EE302: Week 5 - A Brief Intro to C Language 88 88 Call by Value void swapv(int a, int b) { int temp; int main() { int x = 2, y = 3; printf("x=%d\ty=%d\n", x, y); temp = a; a = b; b = temp; swapv(x, y); printf("x=%d\ty=%d\n", x, y); } } Changes made in function swap are lost when the function execution is over EE302: Week 5 - A Brief Intro to C Language 89 89 Call by Pointer void swapp(int *aptr, int *bptr) { int temp; int main() { int x = 2, y = 3; printf("x=%d\ty=%d\n", x, y); temp = *aptr; *aptr = *bptr; *bptr = temp; } swapp(&x, &y); printf("x=%d\ty=%d\n", x, y); } Changes made in function swap are done on original x and y so they do not get lost when the function execution is over EE302: Week 5 - A Brief Intro to C Language 90 90 Memory Organization • When you start a C program, the compiler sets aside memory Memory Layout – for your code and constants (sometimes called code storage or text storage) and – for the global and static variables you define (called static storage). Code • It also sets aside some memory to be used when you call functions, and they need space for their arguments and local variables (that's called stack storage or automatic storage) • The rest of the computer's memory is potentially available for other uses; it is “free”. The C language makes this "free store" (also called the heap) available through an operator called malloc Static Heap Stack Also check http://www.gotw.ca/gotw/009.htm EE302: Week 5 - A Brief Intro to C Language 91 91 Trace a program int main() { int x0 = 5, x1 = 2, x2 = 3; int *p1 = &x1, *p2; p2 = &x2; swapp(&x0, &x1); swapp(p1, p2); printf("x0=%d\tx1=%d\tx2=%d\n" , x0, x1, x2); } Name Addr x0 200 x1 204 x2 208 p1 212 p2 216 …. void swapp(int *a, int *b) a 300 { int tmp; b 304 tmp = *a; *a = *b; tmp 308 *b = tmp; EE302: Week 5 - A Brief Intro to C Language } 92 Value 92 Variable Type, Scope, Visibility, Memory Segment Variable type Defined how/where? Scope/Visibility Life Memory Segment Local Defined inside a block which may be a loop block, conditional block and function block Inside the block after the line where it is defined Till the end of block Stack Static (in a block) As above As above Till the end of program Static Global Defined outside any block Across the files Till the end of program Static Static (outside a block) As above Inside the file only where it is defined – after the line where it is defined Till the end of program Static Using malloc operator. Returned pointer may be kept in local, static or global pointer variable Till free or Free computer store restarts EE302: Week 5 - A Brief Intro to C Language 93 93 “Remember, things take time.” –Piet Hein Enums, structures, unions USER DEFINED TYPES EE302: Week 5 - A Brief Intro to C Language 94 94 Enumerations • An enum (enumeration) is a simple user-defined type, specifying its set of values (its enumerators) • For example: enum Month { jan = 1, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec }; enum Month m = feb; m = 7;// error: can’t assign int to Month int n = m;// error: we can’t get the numeric value of a Month enum Month mm = (enum Month)7;// convert int to Month (unchecked) EE302: Week 5 - A Brief Intro to C Language 95 95 Enumerations – Values • By default // the first enumerator has the value 0, // the next enumerator has the value “one plus the value of the // enumerator before it” enum { horse, pig, chicken };// horse==0, pig==1, chicken==2 • You can control numbering enum { jan = 1, feb, march /* … */ };// feb==2, march==3 enum stream_state { good = 1, fail = 2, bad = 4, eof = 8 }; int flags = fail + eof;// flags==10 enum stream_state s = flags;// error: can’t assign an int to a stream_state enum stream_state s2 = (enum stream_state)flags;// explicit conversion (be careful!) EE302: Week 5 - A Brief Intro to C Language 96 96 Structures & Unions • With a union, you're only supposed to use one of the elements, because they're all stored at the same location – This makes it useful when you want to store something that could be one of several types • A struct, on the other hand, has a separate memory location for each of its elements and they all can be used at once Source: https://stackoverflow.com/questions/346536/difference-between-a-structure-and-a-union-in-c EE302: Week 5 - A Brief Intro to C Language 97 97 Union vs Structure union foo { int a; char b; } foo; // can't use both a and b at once union foo x; x.a = 3; // OK x.b = 'c'; // NO! this affects the value of x.a! printf("%i, %i\n", x.a, x.b); // 99, 99 x.a = 387439; x.b = 'c'; printf("%i, %i\n", x.a, x.b); // 387427, 99 x.a = 0xDEADBEEF; x.b = 0x22; printf("%x, %x\n", x.a, x.b); // deadbe22, 22 struct bar { int a; // can use both a and b simultaneously char b; } bar; struct bar y; y.a = 3; // OK y.b = 'c'; // OK printf("%i, %i\n", y.a, y.b); //3,99 https://stackoverflow.com/questions/346536/difference-between-a-structure-and-a-union EE302: Week 5 - A Brief Intro to C Language 98 98 Bit Fields • • • • To reduce size For (one-bit) flags Improve code readability Atleast int size wide struct { unsigned int is_keyword; unsigned int is_extern; unsigned int is_static; } flags; typedef enum { NORTH = 0, EAST = 1, SOUTH = 2, WEST = 3 } directionValues; struct { unsigned int is_keyword : 1; unsigned int is_extern : 1; unsigned int is_static : 1; } Bitflags; struct { unsigned int alice_dir : 2; unsigned int bob_dir : 2; } directions; directions.bob_dir = SOUTH; EE302: Week 5 - A Brief Intro to C Language 99 99 Six Stages of Debugging 1. 2. 3. 4. 5. 6. That can’t happen That doesn’t happen on my machine That shouldn’t happen Why does that happen? Oh, I see How did that ever work? EE302: Week 5 - A Brief Intro to C Language 100 100