程序代写代做代考 kernel compiler assembly c++ go assembler database graph Java jvm interpreter C Computer Systems Organization

Computer Systems Organization
Sessions 5-9 􏰃 Main Theme C Programming
Dr. Jean-Claude Franchitti
New York University
Computer Science Department Courant Institute of Mathematical Sciences
Presentation material partially based on Lewis Girod CENS S􏰉s􏰇ems Lab􏰋s C T􏰆􏰇orial
Slides copyright © 2020
1

Agenda
1
2
3
Instructor and Course Introduction C Programming
Summary and Conclusion
2

What is the class about?
􏰍Course description and syllabus:
» http://www.nyu.edu/classes/jcf/CSCI-UA.0201-005/
» http://www.cs.nyu.edu/courses/fall20/CSCI-UA.0201-005/ » Accessible via NYU Classes
􏰍 Textbooks:
» Comp􏰆􏰇er S􏰉s􏰇ems: A Programmer􏰋s Perspec􏰇i􏰌e
Randal Br􏰉ant and Da􏰌id O􏰋Hallaron Pearson
ISBN-10: 013409266X, ISBN-13: 978-0134092669, 3rd Edition (03/2015) » Recommended:
» The C Programmning Language, Brian W Kernighan and Dennis Ritchie
Prentice Hall; ISBN-10: 0131103628; ISBN-13: 978-01311103627, 2nd Edition (04/88)
3

Icons / Metaphors
Information
Common Realization Knowledge/Competency Pattern Governance
Alignment
Solution Approach
4
4

C Programming: Detailed Agenda
􏰍 Overview
􏰍 From Writing to Executing Programs 􏰍 Memory, Variables, and Expressions 􏰍 Functions and Pointers
􏰍 Statements
􏰍 Structures, Arrays, and Strings
􏰍 File I/O
􏰍 Macros
􏰍 Summary
5

Agenda
1
2
3
Instructor and Course Introduction C Programming
Summary and Conclusion
6

C Programming
􏰍 Overview
􏰍 From Writing to Executing Programs 􏰍 Memory, Variables, and Expressions 􏰍 Functions and Pointers
􏰍 Statements
􏰍 Structures, Arrays, and Strings
􏰍 File I/O
􏰍 Macros
􏰍 Summary
7

Origin of the C Programming Language
Brian Kernighan Dennis Ritchie
In 1972 Dennis Ritchie at Bell Labs writes C and in 1978 the publication of The C Programming Language by Kernighan & Ritchie caused a revolution in the computing world.
8

Why C?
􏰍 Mainly because it produces code that runs nearly as fast as code written in assembly language. Some examples of the use of C might be:
» Operating Systems
» Language Compilers » Assemblers
» Text Editors
» Print Spoolers
» Network Drivers
» Language Interpreters » Utilities
9

Interesting Opinion About C
You might never use it professionally, but it contains a lifetime of lessons. And the hardest problems, the ones that the top engineers are asked to solve, will sooner or later hit some foundational C code.
Here are some things that are written in C:
􏰍 The Java virtual machine is written in ANSI C
􏰍 Linux is written in C (and some assembly, but mostly C)
􏰍 Python is written in C
􏰍 Mac OS X kernel is written in C
􏰍 Windows is written in C and C++
􏰍 The Oracle database is written in C and C++
􏰍 Cisco routers, those things which connect the Internet, also C
Name anything that is foundational, complex, and performance critical. It was written in C, with a sprinkling of assembly thrown in.
C will make you a better Java programmer. You’ll know when the JVM is using the stack and when it’s using the heap, and what that means. You’ll have a more intuitive sense of what garbage collection does. You’ll have a better sense of the relative performance cost of objects versus primitives.
https://www.quora.com/Financially-speaking-which-computer-languages-can-earn-the-most-for-the-programmer/answer/Carter-Page-1
10

Your first goal: Learn C!
􏰍 Resources
» KR book: 􏰐The C Programming Lang􏰆age􏰑
» These lectures
» Additional online resources ( some links on the course website)
􏰍 Learning a Programming Language
» The best way to learn is to write programs
11

C Programming
􏰍 Overview
􏰍 From Writing to Executing Programs 􏰍 Memory, Variables, and Expressions 􏰍 Functions and Pointers
􏰍 Statements
􏰍 Structures, Arrays, and Strings
􏰍 File I/O
􏰍 Macros
􏰍 Summary
12

Programming Cycle
high level language
low level language
13

Writing and Running Programs
#include
/* The simplest C Program */ int main(int argc, char **argv) {
printf(􏰑Hello World\n􏰤);
return 0; }
1. Write text of program (source code) using a text editor, save as text file e.g. my_program.c
2. Run the compiler, assembler, and linker to convert program from so􏰆rce to an 􏰐executable􏰑 or 􏰐binar􏰉􏰑:
$ gcc 􏰕Wall 􏰕g 􏰕o my_program my_program.c
3-Compiler gives errors and warnings; edit source file, fix it, and re-compile
Run it and see if it works􏰣 $ ./my_program
Hello World
$􏱐
14

Compiling Programs
$ gcc 􏰃Wall 􏰃g 􏰃o my_program my_program.c
generate all warnings
name the generated executable (default: a.out)
keep debugging information
one or more C files
15

About C
􏰍 Procedural language
» Functions calling each other, starting with main().
􏰍 Case-sensitive
16

C Syntax and Hello World
#incl􏰆de inserts another file. 􏰐.h􏰑 files are called 􏰐header􏰑 files. The􏰉 contain st􏰆ff needed to interface to libraries and code in other 􏰐.c􏰑 files.
This is a comment. The compiler ignores this.
The main() function is always where your program starts running.
Blocks of code are marked by
􏱑􏰘􏱒
#include
/* The simplest C Program */
int main(int argc, char **argv)
ur
mum Num ofavg
{
printf(􏰑Hello World\n􏰤);
return 0;
}
Ret􏰆rn 􏰤0􏰋 from this f􏰆nction
Print o􏰆t a message. 􏰤\n􏰋 means 􏰐ne􏰔 line􏰑.
17

Preprocessing
#include
/* The simplest C Program */ int main(int argc, char **argv) {
printf(􏰑Hello World\n􏰤);
return 0; }
__extension__ typedef unsigned
__extension__ typedef unsigned
__extension__ typedef unsigned
__extension__ typedef unsigned
__extension__ typedef unsigned
__extension__ typedef unsigned int __nlink_t;
__extension__ typedef long int
__extension__ typedef long long int __off64_t; extern void flockfile (FILE *__stream) ;
extern int ftrylockfile (FILE *__stream) ; extern void funlockfile (FILE *__stream) ;
int main(int argc, char **argv)
{
printf(􏰑Hello World\n􏰤);
return 0; }
Compile
my_program
long long int __dev_t; int __uid_t;
int __gid_t;
long int __ino_t;
long long int __ino64_t;
__off_t;
Preprocess
18

Preprocessing (continued)
#include
/* The simplest C Program */ int main(int argc, char **argv) {
printf(􏰑Hello World\n􏰤);
return 0; }
__extension__ typedef unsigned
__extension__ typedef unsigned
__extension__ typedef unsigned
__extension__ typedef unsigned
__extension__ typedef unsigned
__extension__ typedef unsigned int __nlink_t;
__extension__ typedef long int
__extension__ typedef long long int __off64_t; extern void flockfile (FILE *__stream) ;
extern int ftrylockfile (FILE *__stream) ; extern void funlockfile (FILE *__stream) ;
int main(int argc, char **argv)
{
printf(􏰑Hello World\n􏰤);
return 0; }
Preprocess
long long int __dev_t; int __uid_t;
int __gid_t;
long int __ino_t;
long long int __ino64_t;
__off_t;
D􏰆ring preprocessing, the so􏰆rce code is 􏰐e􏰒panded􏰑 into a larger form that is simpler for the compiler to 􏰆nderstand. An􏰉 line that starts 􏰔ith 􏰤#􏰋 is a line that is interpreted by the Preprocessor.
􏰏 Incl􏰆de files are 􏰐pasted in􏰑 (#incl􏰆de)
􏰏 Macros are 􏰐e􏰒panded􏰑 (#define)
􏰏 Comments are stripped out ( /* */ , // )
􏰏 Continued lines (i.e. very long lines ) are joined ( \ )
Compile
my_program
19

Compiling
#include
/* The simplest C Program */ int main(int argc, char **argv) {
printf(􏰑Hello World\n􏰤);
return 0; }
__extension__ typedef long int
__extension__ typedef long long int __off64_t; extern void flockfile (FILE *__stream) ;
extern int ftrylockfile (FILE *__stream) ; extern void funlockfile (FILE *__stream) ;
int main(int argc, char **argv)
{
printf(􏰑Hello World\n􏰤);
return 0; }
my_program
Compile
Preprocess
__extension__ typedef unsigned
__extension__ typedef unsigned
__extension__ typedef unsigned
__extension__ typedef unsigned
__extension__ typedef unsigned
__extension__ typedef unsigned int __nlink_t;
long long int __dev_t; int __uid_t;
int __gid_t;
long int __ino_t;
long long int __ino64_t;
__off_t;
􏰏 The compiler then converts the resulting text into binary code the CPU can run directly.
􏰏 The compilation process involves really several steps:
􏰏 Compiler: high level language 􏰗 assembly
􏰏 Assembler: assembly 􏰗 machine code
􏰏 Linker: links all machine code files and needed
libraries into one executable file.
􏰏 When you type gcc you really invoke the
compiler, assembler, and linker.
20

C Programming
􏰍 Overview
􏰍 From Writing to Executing Programs 􏰍 Memory, Variables, and Expressions 􏰍 Functions and Pointers
􏰍 Statements
􏰍 Structures, Arrays, and Strings
􏰍 File I/O
􏰍 Macros
􏰍 Summary
21

What is 􏰑Memor􏰉􏰤?
􏰏 It is like a big table of numbered slots.
􏰏 Each slot stores a byte.
Addr
0
1
Value
􏰏 The slot number ( its index) is its Address.
􏰏 One byte Value can be stored in each slot.
2
3
4
Some 􏰐logical􏰑 data 􏰌al􏰆es span more than one slot, like the character string 􏰐Hello\n􏰑
5
6
A Type names a logical meaning to a span of memory. Some simple types are:
a single character (1 slot)
char
char [10]
int signed 4 byte integer float
an array of 10 characters 4 byte floating point
7
8
9
􏰤H􏰋 (72)
􏰤e􏰋 (101)
􏰤l􏰋 (108)
􏰤l􏰋 (108)
􏰤o􏰋 (111)
􏰤\n􏰋 (10)
10
11
12
􏰤\0􏰋 (0)
22

What is a Variable?
A Variable names a place in memory where you store a Value of a certain Type.
Addr
Value
You first Define a variable by giving it a name and specifying the type, and optionally an initial value
Initial value of x is undefined
char x;
􏰉=􏰋e􏰓;
char
Initial value
The compiler puts them somewhere in memory.
x
y
Symbol
0
1
2
3
4
5
6
7
9
?
􏰤e􏰋 (101)
8
Name
10
Type is single character (char)
11
12
23

Multi-byte Variables
Symbol
Addr
Value
0
1
2
3
x
4
?
y
5
􏰤e􏰋 (101)
6
World boundaries
7
z
8
4
9
3
10
2
11
1
12
Different types consume different amounts of memory. Most architectures store data on 􏰐􏰔ord bo􏰆ndaries􏰑, or e􏰌en m􏰆ltiples of the size of a primitive data type (int, char)
char x;
char 􏰉=􏰋e􏰓;
int z = 0x01020304;
0x means the constant is written in hex
padding
An int consumes 4 bytes
24

Scope
Every Variable is Defined within some scope. A Variable cannot be referenced from outside of that scope.
void p(char x)
{
char y;
char z;
}
char z;
void q(char a)
{
char b;
{
char c;
}
char d;
}
Scopes are defined with curly braces { }.
The scope of Function Arguments is the complete body of the function.
The scope of Variables defined inside a function starts at the definition and ends at the closing brace of the containing block
The scope of Variables defined outside a function starts at the definition and ends at the end of the file. Called Global Vars.
25

Statements
No􏰔 that 􏰔e kno􏰔 abo􏰆t 􏰌ariables, let􏰓s combine them to form expressions!
Expression
X = 2 * Y + Z;
Statement
26

How Expressions Are Evaluated?
Expressions combine Values using Operators, according to precedence.
1+2*2 􏰗1+4 􏰗5 (1+2)*2 􏰗3*2 􏰗6
Comparison operators are used to compare values.
In C: 0 means 􏰐false􏰑, and any other value means 􏰐tr􏰆e􏰑.
int x=4;
(x < 5) (x < 4) ((x < 5) || (x < 4)) 􏰗(4 < 5) 􏰗 􏰗 (4 < 4) 􏰗 0 􏰗( || (x < 4)) 􏰗 Not evaluated because first clause was true
27

Operators Precedence
􏰍 Highest to lowest 􏰏()
􏰏 *, /, % 􏰏 +, –
􏰏 When in doubt, use parenthesis.
􏰏 With operators of the same precedence, expressions
are evaluated left to right.
28

Comparison and Mathematical Operators
== equal to
< less than <= less than or equal > greater than
>= greater than or equal
!= not equal
&& logical and
|| logical or
! logical not
+ plus
– minus * mult
/ divide % modulo
& bitwise and
| bitwise or
^ bitwise xor
~ bitwise not
<< shift left >> shift right
Beware in division:
If second argument is integer, the result will be integer (rounded):
5 / 10􏰗0 whereas 5 / 10.0􏰗0.5
Don􏰋t conf􏰆se & and &&
1 & 2􏰗0 whereas 1 && 2􏰗 29

Assignment Operators
x=y assign y to x x++ post-increment x
x+=yassign(x+y)tox
++x x– –x
pre-increment x
post-decrement x
pre-decrement x
x -= y assign (x-y)
x *= y assign (x*y)
x /= y assign (x/y)
x %= y assign (x%y)
int x=5;
int y;
y = x++; /*x==6,y==5*/
tox tox tox tox
Note the difference between ++x and x++:
int x=5;
int y;
y= ++x;
/* x == 6, y == 6 */
Don􏰋t conf􏰆se = and ==
int x=5;
if (x==6) /* false */ {{
/* … */ /* x is now 6 */ }}
/* x is still 5 */ /* … */
int x=5;
if (x=6) /* always
true */
30

C Programming
􏰍 Overview
􏰍 From Writing to Executing Programs 􏰍 Memory, Variables, and Expressions 􏰍 Functions and Pointers
􏰍 Statements
􏰍 Structures, Arrays, and Strings
􏰍 File I/O
􏰍 Macros
􏰍 Summary
31

What is a Function?
A Function is a series of instructions to run.
You pass Arguments to a function and it returns a Value.
􏰐main()􏰑 is a F􏰆nction. It􏰋s onl􏰉 special beca􏰆se it al􏰔a􏰉s gets called first when you run your program.
Return type, or void
#include
/* The simplest C Program */
main(int argc, char **argv)
{
}
Function Arguments
int
printf(􏰑Hello World\n􏰤);
return 0;
Returning a value
32
􏰐printf()􏰑 is j􏰆st another f􏰆nction, like main(). It􏰋s defined for 􏰉o􏰆 in a 􏰐library􏰑, a collection of functions you can call from your program.

A More Complex Program: pow
#include
float pow(float x, unsigned int exp)
{
/* base case */
if (exp == 0) {
return 1.0; }
/* 􏰑recursive􏰤 case */
return x*pow(x, exp 􏰃 1);
}
int main(int argc, char **argv)
{
float p;
p = pow(10.0, 5);
printf(􏰑p = %f\n􏰤, p);
return 0;
}
Tracing 􏰐po􏰔()􏰑:
􏰏 What does pow(5,0) do? 􏰏 What about pow(5,1)?
33

The 􏰑Stack􏰤
Recall scoping. If a 􏰌ariable is 􏰌alid 􏰐􏰔ithin the scope of a f􏰆nction􏰑, 􏰔hat happens 􏰔hen you call that function recursively? Is there more than one 􏰐exp􏰑?
#include
#include
float pow(float x, unsigned int exp)
{
/* base case */
if (exp == 0) {
return 1.0; }
/* 􏰑recursive􏰤 case */
return x*pow(x, exp 􏰃 1);
}
int main(int argc, char **argv)
{
float p;
printf(􏰑p = %f\n􏰤, p);
return 0; }
Yes. Each f􏰆nction call allocates a 􏰐stack frame􏰑 􏰔here Variables 􏰔ithin that f􏰆nction􏰋s scope will reside.
float x
5.0
uint32_t exp
0
Return 1.0
float x
5.0
uint32_t exp
1
Return 5.0
int argc
1
char **argv
0x2342
float p
5u.n0defined
p = pow(5.0, 1);
Stack, with all its stack frames, resides in memory.
Grows
34

Can a function modify its arguments?
What if we wanted to implement a function pow_assign() that modified its argument, so that these are equivalent:
float p = 2.0;
/* p is 2.0 here */
p = pow(p, 5);
/* p is 32.0 here */
float p = 2.0;
/* p is 2.0 here */
pow_assign(p, 5);
/* p is 32.0 here */
Would this work?
void pow_assign(float x, uint exp)
{
float result=1.0;
int i;
for (i=0; (i < exp); i++) { result = result * x; } x = result; } Pointers: A very powerful but dangerous concept! 35 NO! Remember the stack! void pow_assign(float x, unsigned int exp) { float result=1.0; int i; for (i=0; (i < exp); i++) { result = result * x; } x = result; } main() { float p=2.0; pow_assign(p, 5); } In C, all arguments are passed as values. But, what if the argument is the address of a variable? float x 32.20.0 uint32_t exp 5 float result 31.20.0 float p 2.0 Grows 36 Passing Addresses Symbol Addr Value 0 1 2 3 char x 4 􏰤H􏰋 (72) char y 5 􏰤e􏰋 (101) 6 7 8 9 10 11 12 address of x􏰗4 memory content at address 4􏰗72 37 􏰑Pointers􏰤 This is e􏰒actl􏰉 ho􏰔 􏰐pointers􏰑 􏰔ork. 􏰏 address of x: &x 􏰏 if y is an address, the } content of the memory at that address 􏰗 *y /* y is 101 */ /* i.e. f(5) */ A 􏰐pointer t􏰉pe􏰑: pointer to char void f(char * p) { *p = *p - 32; char y = 101; f(&y); /* y is now 101-32 = 69 */ Pointers are used in C for many other purposes: 􏰏 Passing large objects without copying them 􏰏 Accessing dynamically allocated memory 􏰏 Referring to functions 38 Pointer Validity A Valid pointer is one that points to memory that your program controls. Using invalid pointers will cause non-deterministic behavior, and will often cause Linux to kill your process (SEGV or Segmentation Fault). There are two general causes for these errors: 􏰏 Program errors that set the pointer value to a strange number 􏰏 Use of a pointer that was at one time valid, but later became invalid Will ptr be valid or invalid? char * get_pointer() { char x=0; return &x; } main() { char * ptr = get_pointer(); *ptr = 12; /* valid? */ } 39 Answer: Invalid! A pointer to a variable allocated on the stack becomes invalid when that 􏰌ariable goes o􏰆t of scope and the stack frame is 􏰐popped􏰑. The pointer will point to an area of the memory that may later get reused and rewritten. char * get_pointer() { char x=0; return &x; } main() { char * ptr = get_pointer(); *ptr = 12; /* valid? */ other_function(); } But now, ptr points to a location that􏰋s no longer in use, and will be reused the next time a function is called! 101 cichnatraxvxerage Return 101 014256603 100 char * ptr 1?01 Grows 40 C Programming 􏰍 Overview 􏰍 From Writing to Executing Programs 􏰍 Memory, Variables, and Expressions 􏰍 Functions and Pointers 􏰍 Statements 􏰍 Structures, Arrays, and Strings 􏰍 File I/O 􏰍 Macros 􏰍 Summary 41 The 􏰑for􏰤 loop The 􏰐for􏰑 loop is j􏰆st shorthand for this 􏰐􏰔hile􏰑 loop str􏰆ct􏰆re. float pow(float x, unsigned int exp) { float result=1.0; int i; i=0; while { result = result * x; } return result; } int main(int argc, char **argv) { float p; p = pow(10.0, 5); printf(􏰑p = %f\n􏰤, p); return 0; } float pow(float x, unsigned int exp) { float result=1.0; int i; for { result = result * x; } return result; } int main(int argc, char **argv) { float p; p = pow(10.0, 5); printf(􏰑p = %f\n􏰤, p); return 0; } (i=0; (i < exp); i++) (i < exp) i++; 42 When to Use? Different Loop-constructs 􏰍 while 􏰍 do-while 􏰍 for Conditions 􏰍 if-else 􏰍 switch-case 43 C Programming 􏰍 Overview 􏰍 From Writing to Executing Programs 􏰍 Memory, Variables, and Expressions 􏰍 Functions and Pointers 􏰍 Statements 􏰍 Structures, Arrays, and Strings 􏰍 File I/O 􏰍 Macros 􏰍 Summary 44 More on Types No􏰔 that 􏰔e kno􏰔 pointers (I hope!), let􏰓s go back to t􏰉pes 􏰘 We􏰋􏰌e seen a fe􏰔 t􏰉pes at this point: char, int, float, char * Types are important because: 􏰏 They allow your program to impose logical structure on memory 􏰏 The􏰉 help the compiler tell 􏰔hen 􏰉o􏰆􏰋re making a mistake In the next slides we will discuss: 􏰏 How to create logical layouts of different types (structs) 􏰏 How to use arrays 􏰏 How to parse C type names (there is a logic to it!) 􏰏 How to create new types using typedef 45 Structures 􏰍 a collection of related data items 􏰍 possibly of different types 􏰍 defined using the keyword struct 􏰍 The members of a struct type variable are accessed with the dot (.) operator: .
46

􏰑str􏰆ct􏰤 Basics
􏰍 Definition of a structure:
struct {
;
;

};
Each identifier defines a member of the structure.
47

􏰑str􏰆ct􏰤 Basics (contin􏰆ed)
􏰍 Example: struct Address {
Example
main() {
struct Address adrs; 􏰘
adrs.zip = 10012; }
int zip;
char street[50];
char city[20];
};
Example of initializing a structure
struct Address adrs = 􏱑10012, 􏰐Me􏰈ce􏰈􏰑, 􏰐Ne􏰔 Yo􏰈k􏰑􏱒;
48

Arrays
Arrays in C are composed of a particular type, laid out in memory in a repeating pattern. Array elements are accessed by stepping forward in memory from the base of the array by a multiple of the element size.
Brackets specify the count of elements. Initial values optionally set in braces.
Arrays in C are 0-indexed (here, 0..9)
􏰒[3] == *(􏰒+3) == 􏰤t􏰋 (NOT 􏰤s􏰋!)
/* define an array of 5 chars */
char 􏰒[5] = 􏱑􏰋t􏰓,􏰓e􏰓,􏰓s􏰓,􏰓t􏰓,􏰓\0􏰓􏱒;
/* accessing element 0 */
􏰒[0] = 􏰋T􏰓;
/* pointer arithmetic to get elt 3 */
char elt3 = *(x+3); /* x[3] */
/* x[0] evaluates to the first element;
* x evaluates to the address of the
* first element, or &(x[0]) */
Symbol
Addr
Value
char x [0]
100
􏰤t􏰋
char x [1]
101
􏰤e􏰋
char x [2]
102
􏰤s􏰋
char x [3]
103
􏰤t􏰋
char x [4]
104
􏰤\0􏰋
49

Pointers and Arrays in C
􏰍 An array name by itself is an address, or pointer in C.
􏰍When an array is declared, the compiler allocates sufficient space beginning with some base address to accommodate every element in the array.
􏰍The base address of the array is the address of the first element in the array (index position 0).
»Example: intnum[10];
&num[0] is the same as num
50

Pointers and Arrays in C (continued)
􏰍 Suppose we define the following array and pointer: int a[100]; int *ptr;
Assume that the system allocates memory bytes 400, 404, 408, …, 796 to the array. Integers are allocated 32 bits = 4 bytes.
» The two statements: ptr = a; and ptr = &a[0]; are equivalent and would assign the value of 400 to ptr.
􏰍 Pointer arithmetic provides an alternative to array indexing in C.
» The two statements: ptr = a + 1; and ptr = &a[1]; are equivalent and would assign the value of 404 to ptr.
51

Pointers and Arrays in C (continued)
􏰍Assuming the elements of the array of integer have been assigned values, the following code would sum the elements of the array:
Ca b aEb
sum = 0;
for (ptr = a; ptr < &a[100]; ++ptr) Atb sum += *ptr; 􏰍 Here is another way to sum the array: sum = 0; for (i = 0; i < 100; ++i) sum += *(a + i); Atb a[b] in C is just syntactic sugar for *(a + b) 52 Strings 􏰍 Series of characters treated as a single unit 􏰍 Can include letters, digits, and certain special characters (*, /, $) 􏰍 String literal (string constant) - written in double quotes » "Hello" 􏰍 Strings are arrays of characters 􏰍 Each character is represented in numerical code called ASCII code. 􏰍 Example: » char name[] = 􏰐test􏰑; » address of the above string can be expressed in two ways: 􏰏 &name[0] 􏰏 name 53 ASCII code 54 Strings 􏰍 String declarations » Declare as a character array or a variable of type char * char color[] = "blue"; char *colorPtr = "blue"; » Remember that strings represented as character arrays end with '\0' • color has 5 elements 􏰍 Inputting strings » Use scanf char word[10]; scanf("%s", word); 􏰏 Copies input into word[], which does not need & (because a string is a pointer) » Remember to leave space for '\0' 55 Character Handling Library 􏰍 In
Prototype Description
int isdigit( int c )
int isalpha( int c )
int isalnum( int c )
int isxdigit( int c )
int islower( int c )
int isupper( int c )
int tolower( int c )
int toupper( int c )
int isspace( int c )
int iscntrl( int c )
int ispunct( int c )
Returns true if c is a digit and false otherwise. Returns true if c is a letter and false otherwise.
Returns true if c is a digit or a letter and false otherwise.
Returns true if c is a hexadecimal digit character and false otherwise.
Returns true if c is a lowercase letter and false otherwise.
Returns true if c is an uppercase letter; false otherwise.
If c is an uppercase letter, tolower returns c as a lowercase letter. Otherwise, tolower returns the argument unchanged.
If c is a lowercase letter, toupper returns c as an uppercase letter. Otherwise, toupper returns the argument unchanged.
Returns true if c is a white-space character—newline (‘\n’), space (‘ ‘), form feed (‘\f’), carriage return (‘\r’), horizontal tab (‘\t’), or vertical tab (‘\v’)—and false otherwise
Returns true if c is a control character and false otherwise.
Returns true if c is a printing character other than a space, a digit, or a letter and false
otherwise.
Returns true value if c is a printing character including space (‘ ‘) and false otherwise.
Returns true if c is a printing character other than space (‘ ‘) and false otherwise. Each function receives a character (an int) or EOF as an argument
int isprint( int c )
int isgraph( int c )
56

String Conversion Functions
􏰍 Conversion functions
» In (general utilities library)
» Convert strings of digits to integer and floating-point values
Prototype
Description
double atof( const char *nPtr )
Converts the string nPtr to double.
int atoi( const char *nPtr )
Converts the string nPtr to int.
long atol( const char *nPtr )
Converts the string nPtr to long int.
double strtod( const char *nPtr, char **endPtr )
Converts the string nPtr to double.
long strtol( const char *nPtr, char **endPtr, int base )
Converts the string nPtr to long.
unsigned long strtoul(const char *nPtr, char **endPtr, int base)
Converts the string nPtr to unsigned long.
57

String Manipulation Functions
􏰍 In
􏰍 String handling library has functions to » Manipulate string data
» Search strings
» Determine string length
Function prototype
Function description
char *strcpy( char *s1,
const char *s2 )
Copies string s2 into array s1. The value of s1 is returned.
char *strncpy( char *s1,
const char *s2, size_t n )
Copies at most n characters of string s2 into array s1. The value of s1 is returned.
char *strcat( char *s1,
const char *s2 )
Appends string s2 to array s1. The first character of s2 overwrites the terminating null character of s1. The value of s1 is returned.
char *strncat( char *s1,
const char *s2, size_t n )
Appends at most n characters of string s2 to array s1. The first character of s2 overwrites the terminating null character of s1. The value of s1 is returned.
58

String Manipulation Functions (continued)
int strcmp ( const char * str1, const char * str2 )
return value
<0 0 >0
indicates
the first character that does not match has a lower value in ptr1 than in ptr2
the contents of both strings are equal
the first character that does not match has a greater value in ptr1 than in ptr2
59

How to Parse C Types
C type names are parsed by starting at the name and working outwards according to the rules of precedence:
x is
an array of
pointers to
int
int *x[10];
int (*x)[10];
x is
a pointer to
an array of
int
60

Using typedef
At this point we have seen a few basic types, arrays, pointer types, and str􏰆ct􏰆res. So far 􏰔e􏰋􏰌e glossed o􏰌er ho􏰔 t􏰉pes are named.
int x;
int *y;
int z[10];
/* int;
/* pointer to int;
/* array of ints;
*/ typedef int T;
*/ typedef int *U;
*/ typedef int V[10];
typedef defines a new type
Now:
Tx; isthesameasintx; U y; is the same as int * y; and so on 􏰘
61

Dynamic Memory Allocation
What if 􏰉o􏰆 􏰔ant to allocate an arra􏰉 of N elements, and 􏰉o􏰆 don􏰓t kno􏰔 N beforehand?
So far all of our examples have allocated variables statically by defining them in our program. This allocates them in the stack.
But, what if we want to allocate variables based on user input or other dynamic inputs, at run-time? This requires dynamic allocation.
sizeof() reports the size of a type in bytes
int * alloc_ints(size_t requested_count)
{
int * big_array;
big_array = (int *)calloc(requested_count, sizeof(int));
if (big_array == NULL) {
printf(􏰑can􏰓t allocate %d ints: %m\n􏰤, requested_count);
return NULL;
}
/* now big_array[0] .. big_array[requested_count-1] are
* valid and zeroed. */
return big_array;
}
calloc(N, K) allocates memory for N elements of size k
Ret􏰆rns NULL if can􏰋t alloc
It􏰋s OK to ret􏰆rn this pointer. It will remain valid until it is freed with free()
62

Dynamic Memory Allocation (continued)
􏰍 void *malloc (size_t size);
􏰍 void* calloc (size_t num, size_t size);
􏰍 void free (void* ptr);
􏰍 Unary operator sizeof is used to determine the size in bytes of any data type. Examples:
» sizeof(double) » sizeof(int)
63

Caveats with Dynamic Memory
Dynamic memory is useful. But it has several caveats:
Whereas the stack is automatically reclaimed, dynamic allocations must be tracked and free()􏰋d 􏰔hen the􏰉 are no longer needed. With e􏰌er􏰉 allocation, be sure to plan how that memory will get freed. Losing track of memor􏰉 is called a 􏰐memor􏰉 leak􏰑.
Whereas the compiler enforces that reclaimed stack space can no longer be reached, it is easy to accidentally keep a pointer to dynamic memory that has been freed. Whenever you free memory you must be certain that you will not try to use it again. It is safest to erase any pointers to it.
Because dynamic memory always uses pointers, there is generally no way for the compiler to statically verify usage of dynamic memory. This means that errors that are detectable with static allocation are not with dynamic
64

Pointers and Structures
􏰍 Assume we have a structure called node: struct node{
int number;
struct node * link; };
􏰍 Inserting a node in a linked list of nodes (with head pointer called pHead and pPre initially points to the node just before the insertion point):
struct node *pNew;
pNew = (struct node *) malloc(sizeof(struct node)); pNew -> data = item;
if (pPre == NULL){
//add before first node or to an empty list pNew -> next = pHead;
pHead = pNew; }
else {
//add in the middle or at the end
pNew -> next = pPre -> next; // Ppre points to previous node
pPre -> next = pNew; }
number
link
65

Pointers and Structures
pNew
Before
55
124
pPre
pNew
After
55
124
pPre
64
64
66

C Programming
􏰍 Overview
􏰍 From Writing to Executing Programs 􏰍 Memory, Variables, and Expressions 􏰍 Functions and Pointers
􏰍 Statements
􏰍 Structures, Arrays, and Strings
􏰍 File I/O
􏰍 Macros
􏰍 Summary
67

I/O
􏰍 reading from:
» standard input (usually the keyboard) » file
􏰍 writing to:
» standard output (usually the screen) » file
􏰍 A library of functions is supplied to perform these operations.
􏰍 The I/O library functions are listed the header file .
68

Writing to stdout
printf ( ) ;
􏰍 This function provides for formatted output to the screen. The syntax is:
printf ( 􏰐format􏰑, 􏰌ar1, 􏰌ar2, 􏰘 ) ;
􏰍 The 􏰐format􏰑 incl􏰆des a listing of the data t􏰉pes of the variables to be output and, optionally, some
text and control character(s)
􏰍
􏰍 Example:
float a ; int b ;
scanf ( 􏰐%f%d􏰑, &a, &b ) ;
printf ( 􏰐Yo􏰆 entered %f and %d \n􏰑, a, b ) ;
69

Formatted Output with printf
Format Conversion Specifiers (This list is not exhaustive):
d — displays a decimal (base 10) integer
l — used with other specifiers to indicate a long f — displays a floating point value
x — displays a number hexadecimal format
c — displays a single character
s — displays a string of characters
70

Reading from stdin
scanf ( ) ;
􏰍 This function provides for formatted input from the keyboard. The syntax is:
scanf ( 􏰐format􏰑 , &􏰌ar1, &􏰌ar2, 􏰘) ;
􏰍 The 􏰐format􏰑 is a listing of the data t􏰉pes of the 􏰌ariables to be input and the & in front of each variable name tells the system WHERE to store the value that is input; it provides the address for the variable
􏰍 Example:
float a; int b;
scanf (􏰐%f%d􏰑, &a, &b);
71

Files
􏰍 In C, each file is simply a sequential stream of bytes.
􏰍 C imposes no structure on a file.
􏰍 Steps to deal with files
» open a file
» check that the open was successful » read/write to a file
» close a file
72

First step
􏰍 Declaration:
FILE *fptr1, *fptr2 ;
73

Opening Files
􏰍 The statement:
fptr1 = fopen ( 􏰐filename”, “r” ) ;
would open the file filename for input (reading).
» r: read
» w: write
» a: append
» 􏰘 there are some more
74

Testing for Successful Open
􏰍 If the file was not able to be opened, then the value returned by the fopen routine is NULL.
􏰍 For example, let’s assume that the file mydata does not exist. Then:
FILE *fptr1 ;
fptr1 = fopen ( “myfile”, “r”) ; if (fptr1 == NULL)
{
printf (“File ‘mydata’ did not open.\n”) ; }
75

Reading From Files
􏰍 In the following segment of C language code:
int a, b ;
FILE *fptr1, *fptr2 ;
fptr1 = fopen ( “mydata”, “r” ) ; fscanf ( fptr1, “%d%d”, &a, &b) ;
the fscanf function would read values from the file “pointed” to by fptr1 and assign those values to a and b.
76

End of File
􏰍 The end-of-file indicator informs the program when there are no more data (no more bytes) to be processed.
􏰍 There are a number of ways to test for the end-of-file condition. One is to use the feof function which returns a true or false condition:
fscanf (fptr1, “%d”, &var) ; if ( feof (fptr1) )
{
printf (“End-of-file encountered.\n􏰑);
}
􏰍 Another (better) way of testing EOF: while(fscanf(fp,”%d “, &current) == 1) {
}
77

Writing To Files
int a = 5, b = 30;
FILE *fptr2 ;
fptr2 = fopen ( 􏰐filename”, “􏰔” ) ; fprintf ( fptr2, “%d %d\n”, a, b ) ;
the fprintf functions would write the values stored in a and b to the file “pointed” to by fptr2.
78

Closing Files
fclose ( fptr1 ) ;
Once the files are open, they stay open until you close them or end the program (which will close all files.)
79

C Programming
􏰍 Overview
􏰍 From Writing to Executing Programs 􏰍 Memory, Variables, and Expressions 􏰍 Functions and Pointers
􏰍 Statements
􏰍 Structures, Arrays, and Strings
􏰍 File I/O
􏰍 Macros
􏰍 Summary
80

Macros
Macros can be a useful way to customize your interface to C and make your code easier to read and less redundant. However, when possible, use a static inline function instead.
Format is very simple:
#define identifier replacement-text
Example:
#define NUM 10
Notes:
􏰏 Each occurrence of NUM in your code will be replaced by 10.
􏰏 This happens by the preprocessor before compilation.
􏰏 In the rest of the code you cannot change NUM.
We can take this idea further; instead of defining a constant, we define operations 81

Macros
􏰏 Sophisticated Example
#define CIRCLE_AREA( x ) ( PI * ( x ) * ( x ) ) area = CIRCLE_AREA( 4 );
becomes
area = ( 3.14159 * ( 4 ) * ( 4 ) );
􏰕 See how parentheses are used. Always enclose parameters in ().
􏰏 More sophisticated example: #defineRECTANGLE_AREA(x,y) ((x)*(y)) rectArea = RECTANGLE_AREA( a + 4, b + 7 );
becomes
rectArea = ( ( a + 4 ) * ( b + 7 ) );
82

Macros: More examples
􏰍#defineforeover for(;;)
􏰍 #define max(i,j) ((i) > (j) ? (i) : (j))
􏰍 #define SWAP(a, b) { \ a^=b; \
b ^= a; \
a ^= b; \ }
83

C Programming: Summary
􏰍 We took a quick look at the different features of C
􏰍 To get deeper look: check online tutorials. You will find C Programming Resources on the course webpage
􏰍 To become an e􏰒pert: 􏰔rite code 􏰘 􏰔rite code 􏰘 􏰔rite code
84

Agenda
1
2
3
Instructor and Course Introduction C Programming
Summary and Conclusion
85

Assignments & Readings
􏰍 Readings
» Slides and Handouts posted on the course web site
» Recommended Textbook: The C Programming Language (K&R) » C Programming Resources
􏰍 Assignment #1 / Lab #1
» Lab #1 TBD in later sessions
􏰍 Development environment
» C development environment setup
» Create GitHub account
» See Announcements regarding invitation to join the course GitHub and related instructions to access the materials for the course and recitations (including private versions of them that you will work on during recitations)
86

Next Session: Machine-Level Programming
87

Questions, Comments, Discussions ?
88