CS代写 Professor G. slides adapted by G. Sandoval from slide by -Gavitt

Professor G. slides adapted by G. Sandoval from slide by -Gavitt

 Just kidding, it takes longer than that!  But we’ll cover the basics in class today  For more details, you can consult:
▪ Learn C DOT ORG: http://www.learn-c.org

Copyright By PowCoder代写 加微信 powcoder

▪ Zed Shaw, Learn C the Hard Way
This book has lots of challenging exercises. https://www.amazon.com/Learn- Hard-Way-Practical-Computational/dp/0321884922
▪ and , The C Programming Language https://archive.org/details/TheCProgrammingLanguage
▪ Head first C: I enjoyed this book when I was teaching C about 5 years ago. https://www.amazon.com/Head-First-C-Brain-Friendly- Guide/dp/1449399916

 Let’s write a C program that prints the string “Hello world”

Include file: similar to “import” in Python

Declaration of function “main”, returning type “int”

Calling the printf function with a string parameter

Each statement must end with a semicolon

Return the value 0

$ gcc hello.c -o hello $ ./hello
Hello, world

 Where exactly do you run gcc?
 At the command line
 On OS X, this is in the Terminal App (/Applications/Utilities)
 In Linux, xterm, gnome-terminal, etc. are all fine
 On Windows – use the bash shell

 Invoking gcc on hello.c did the following things:
1. Called the C preprocessor (cpp) on hello.c
2. cpplookedforstdio.hinthedefaultincludepath (a set of directories where header files live) and then recursively called itself on stdio.h
3. The output of that process was pasted into hello.c, and the result was compiled by gcc into an executable binary

 Remembering and reproducing the commands to compile a project is tedious
 Larger projects may have multiple files, many compilation options, external libraries, etc.
 To manage this complexity we can use a Makefile

 Instead of calling gcc, we can instead just do: $ make hello
cc hello.c -o hello
 The make command has some built-in rules that understand how to compile basic C and C++ programs
 The make command will check whether the file “hello” exists and is newer than the file “hello.c”; if not, it will try to build “hello” using “hello.c”

 For more complex rules, or to build things that make doesn’t natively understand how to create, we use a Makefile:
CFLAGS=-Wall -g
rm -f hello
Extra compile flags. Will be treated as if passed as args to gcc
 Now we can have make clean up for us: $ make clean
rm -f hello

 For more complex rules, or to build things that make doesn’t natively understand how to create, we use a Makefile:
CFLAGS=-Wall -g
rm -f hello
 Now we can have make clean up for us: $ make clean
rm -f hello
The name of our new build target

 For more complex rules, or to build things that make doesn’t natively understand how to create, we use a Makefile:
CFLAGS=-Wall -g
rm -f hello
 Now we can have make clean up for us: $ make clean
rm -f hello
The command to run to build the target

 For more complex rules, or to build things that make doesn’t natively understand how to create, we use a Makefile:
CFLAGS=-Wall -g
rm -f hello
The command to run to build the target
 Now we can have make clean up for us: $ make clean
rm -f hello
NOTE: this must be a tab character, not spaces!

– New program:
– Write a C program that prints your age and height.
– No need to input anything, you can hardcode both age and height.
– Compile and run it!

Variable type Variable name
Initial value

char A single byt, capable of holding one character in the local
character set
int An integer, typically reflecting the natural size of integers in the local
float Single precision floating point
Double Double precision floating point
-128 to 127
-2147483648 To 2147483647
32 bit IEEE floating point 32 bit IEEE floating point
 Note: some of these ranges are different on different platforms and implementations of C. Here I’m giving the ranges for 32-bit x86, which is what we’ll be working with this semester. More precise details can be found by consulting the C language specification.

 Arithmetic:
▪ + (plus), – (minus), / (division), * (multiplication),
% (modulus)
▪ && (and), || (or), ! (not)
 Relational
▪ < (less than), > (greater than), >= (greater or equal), <= (less or equal), == (equal), != (not equal)  Binary arithmetic ▪ ~x: one's complement (i.e., flip all bits) ▪ x << n: shift x left by n bits ▪ x >> n: shift y right by n bits
▪ x & y: bitwise AND of x and y
▪ x | y: bitwise OR of x and y
▪ x ^ y: bitwise XOR of x and y

 Branching:
▪ if (condition) { statements
else if (condition) {
statements
statements

 Branching:
▪ switch (expression) { case 1:
statements
break; case 2:
statements
break; default:
statements

while (condition) { statements
statements
} while (condition);

for (init ; condition ; update) { statements
for (i = 0; i < 100; i = i + 1) { printf("This is iteration %d\n", i); }  Breakout:  "Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”."  All code in C lives in a function  Declaring a function is simple: int add(double x, double y) { return x + y;  Calling it is simple too int result = add(4.9, 12.1);  All code in C lives in a function  Declaring a function is simple: Return type Function name int add(double x, double y) { return x + y; Parameters  Calling it is simple too int result = add(4.9, 12.1);  x = y: simple assignment Note: x = y is an expression, and evaluates to the right hand side. So, you can do things like if ((x = y) > 0) …
which will assign x the value of y and branch if y is greater than 0
 x += y: same as x = x + y
▪ -=, *=, /=, <<=, >>=, %=, &=, |=

 (Pre/Post) Increment/decrement ▪ x++: evaluate x, then increment it
▪ ++x: increment x, then evaluate it
▪ x–: evaluate x, then decrement it
▪ –x: decrement, then evaluate it

#include
int main() { int x = 0;
if (x++ > 0) {
// 1 will be printed ?
if (x > 0) {
// 2 will be printed ? }
if (++x > 0) {
// 3 will be printed ?
if (x > 0) {
// 4 will be printed ? }
return 0; }

#include
int main() { int x = 0;
if (x++ > 0) {
printf(“This will not be printed\n”);
if (x > 0) {
printf(“This will be printed\n”); }
if (++x > 0) {
printf(“This will be printed\n”); }
if (x > 0) {
printf(” This will be printed \n”);
return 0; }

 Arrays in C are fixed-length (their size must be specified at compile time)
 To declare an array: int x[10];
 Then individual elements are accessible as x[i] where i is an integer

Array Bounds
 Unlike higher-level languages, C does not check array bounds
▪ In some simple cases, the compiler can detect when you access an out-of-bounds element, but it’s not part of the language
 Programming in C requires you to be very careful when programming; there are basically no safety features

cosimo:lec2 moyix$ gcc oob.c -o oob
oob.c:6:5: warning: array index 10 is past the end of the array (which contains5 elements) [-Warray-bounds]
x[10] = 9;
oob.c:4:5: note: array ‘x’ declared here int x[5];
oob.c:8:28: warning: array index 10 is past the end of the array (which contains 5 elements) [-Warray-bounds]
printf(“x[10] = %d\n”, x[10]);
oob.c:4:5: note: array ‘x’ declared here int x[5];
2 warnings generated. cosimo:lec2 moyix$ ./oob x[10] = 9
Segmentation fault: 11

 Strings in C are a special case of arrays
 A C string is an array of characters, where the
final element in the array is NULL (‘\0’)  So:
char hello[] = “hi”;
 is the same as
char hello[] = {‘h’, ‘i’, ‘\0’};

 C has a special kind of variable called a pointer  Pointers hold the address of another variable  To declare:
 Two new operators:
&x : get the address of x
*p : access the value of the pointed-to variable
(called dereferencing)

0xbff9cb4c 0xbff9cb50 0xbff9cb54

pNULL y20x10 0xbff9cb4c 0xbff9cb50 0xbff9cb54

At the start, x = 10, y = 20, p = 0x0
Pointer at 0xbff9cb4c
has value 0xbff9cb54 and points to var with value 10
After assigning to *p, x = 5
Pointer at 0xbff9cb4c
has value 0xbff9cb50 and points to var with value 20
After assigning to *p, y = 50
pNULL y20x10 0xbff9cb4c 0xbff9cb50 0xbff9cb54

0xbff9cb4c
0xbff9cb54
y 20 0xbff9cb50
At the start, x = 10, y = 20, p = 0x0
Pointer at 0xbff9cb4c
has value 0xbff9cb54 and points to var with value 10
After assigning to *p, x = 5
Pointer at 0xbff9cb4c
has value 0xbff9cb50 and points to var with value 20
After assigning to *p, y = 50
x 10 0xbff9cb54

0xbff9cb4c
0xbff9cb54
y 20 0xbff9cb50
At the start, x = 10, y = 20, p = 0x0
Pointer at 0xbff9cb4c
has value 0xbff9cb54 and points to var with value 10
After assigning to *p, x = 5
Pointer at 0xbff9cb4c
has value 0xbff9cb50 and points to var with value 20
After assigning to *p, y = 50
x 10 0xbff9cb54

0xbff9cb4c
0xbff9cb54
y 20 0xbff9cb50
At the start, x = 10, y = 20, p = 0x0
Pointer at 0xbff9cb4c
has value 0xbff9cb54 and points to var with value 10
After assigning to *p, x = 5
Pointer at 0xbff9cb4c
has value 0xbff9cb50 and points to var with value 20
After assigning to *p, y = 50
x 5 0xbff9cb54

0xbff9cb4c
0xbff9cb54
y 20 0xbff9cb50
At the start, x = 10, y = 20, p = 0x0
Pointer at 0xbff9cb4c
has value 0xbff9cb54 and points to var with value 10
After assigning to *p, x = 5
Pointer at 0xbff9cb4c
has value 0xbff9cb50 and points to var with value 20
After assigning to *p, y = 50
x 5 0xbff9cb54

0xbff9cb4c
0xbff9cb50
y 20 0xbff9cb50
At the start, x = 10, y = 20, p = 0x0
Pointer at 0xbff9cb4c
has value 0xbff9cb54 and points to var with value 10
After assigning to *p, x = 5
Pointer at 0xbff9cb4c
has value 0xbff9cb50 and points to var with value 20
After assigning to *p, y = 50
x 5 0xbff9cb54

0xbff9cb4c
0xbff9cb50
y 20 0xbff9cb50
At the start, x = 10, y = 20, p = 0x0
Pointer at 0xbff9cb4c
has value 0xbff9cb54 and points to var with value 10
After assigning to *p, x = 5
Pointer at 0xbff9cb4c
has value 0xbff9cb50 and points to var with value 20
After assigning to *p, y = 50
x 5 0xbff9cb54

0xbff9cb4c
0xbff9cb50
y 50 0xbff9cb50
At the start, x = 10, y = 20, p = 0x0
Pointer at 0xbff9cb4c
has value 0xbff9cb54 and points to var with value 10
After assigning to *p, x = 5
Pointer at 0xbff9cb4c
has value 0xbff9cb50 and points to var with value 20
After assigning to *p, y = 50
x 5 0xbff9cb54

0xbff9cb4c
0xbff9cb50
y 50 0xbff9cb50
At the start, x = 10, y = 20, p = 0x0
Pointer at 0xbff9cb4c
has value 0xbff9cb54 and points to var with value 10
After assigning to *p, x = 5
Pointer at 0xbff9cb4c
has value 0xbff9cb50 and points to var with value 20
After assigning to *p, y = 50
x 5 0xbff9cb54

■ Call-by-value: Changes made to arguments passed to a function aren’t reflected in the calling function
■ Call-by-reference: Changes made to arguments passed to a function are reflected in the calling function
■ C is a call-by-value language
■ To cause changes to values outside the function, use pointers
■ Do not assign the pointer to a different value (that won’t be reflected!)
■ Instead, dereference the pointer and assign a value to that address

■ Example:
■ Write a function called swap that given two integers it swaps it’s values:

■ Example:
■ Write a function called swap that given two integers it swaps it’s values:

■ Example:
■ Write a function called swap that given two integers it swaps it’s values:

 Variables of different types can be converted to one another
 For example: prints
int x = 10;
float y = x;
printf(“x = %d, y = %f\n”, x, y);
x = 10, y = 10.000000
 The details of this are somewhat complicated, but a general rule is that things can be converted automatically as long as you aren’t losing precision

 Some conversions need an explicit cast – a way of telling C that you really do want that conversion
 For example:
int x = 90000;
short y = (short) x;
printf(“x = %d, y = %d\n”, x, y); prints
x = 90000, y = 24464

 Pointers of one type can be cast to another type
 As usual, C does not stop you from shooting yourself in the foot with this
 But it does let you do some handy things too!

POLY is 1498173264

POLY is 1498173264

POLY is 1498173264
“POLY” = {‘P’, ‘O’, ‘L’, ‘Y’, ‘\0’}
= 0x50, 0x4f, 0x4c, 0x59, 0x00
= 0x594c4f50 = 1498173264

1498173264 is POLY

 Sometimes we want more complicated data types than just int, char, etc.
 For this we can define a struct – an aggregate type that contains several fields

 If you have a pointer to a structure, you can dereference the pointer and access its member in one step:
struct Person *p = &q; p->age = 64;

 file, sh.c, creates several structs and casts between them in order to mimic inheritance

 The switch statement uses the type field of a struct cmd, which they all share, to decide the correct type to cast to

 You can make pointers point to anything you like, really
it’s something sensible
 Sometimes this is actually useful, particularly
when writing code that talks directly to hardware
Though you are responsible for making sure
Writes 10 at address 0x12345678

 Arrays and pointers have a special relationship in C
 An array can be treated as a pointer in most contexts, and vice versa
 If you hand an array of type T to something that expects a pointer to type T, it’s treated as if it were a pointer to the first element of the array

 You can do arithmetic on pointers
Given a pointer P of type T, P + N will point to
the memory at address P + (N * sizeof(T))  For example:
 => Prints “*p = 3”

 You may have noticed that x[2] and *(p + 2) refer to the same element
 This is not an accident!
 In fact, we can use array index notation with
pointers as well:
 => Prints “p[2] = 3”

 Recall that I said C only supports fixed-length arrays
 So how do you deal with variable amounts of data?
 To allocate: p = malloc(size in bytes) – returns a pointer to a memory region that
you can then assign to a variable of whatever
type you like
 To free: free(p)

Memory Management Rules
■ Malloc what you free, free what you malloc
■ client should free memory allocated by client code
■ library should free memory allocated by library code
■ Number mallocs = Number frees
■ Number mallocs > Number Frees: definitely a memory leak
■ Number mallocs < Number Frees: definitely a double free ■ Free a malloced block exactly once ■ Should not dereference a freed memory block ■ Don’t put too much data on malloced memory ■ Make sure you allocate extra space for NULL on strings Stack Vs Heap Allocation ■ Local variables and function arguments are placed on the stack ■ deallocated after the variable leaves scope ■ do not return a pointer to a stack-allocated variable! ■ do not reference the address of a variable outside its scope! ■ Memory blocks allocated by calls to malloc/calloc are placed on the heap ■ Globals, constants are placed elsewhere ■ Example: ■ // a is a pointer on the stack to a memory block on the heap ■ int* a = malloc(sizeof(int)); struct list { int data; struct list *next; }; struct list * list_insert(struct list *head, int data) { /* Write code for insert */ struct list * list_insert(struct list *head, int data) { struct list *new = malloc(sizeof(struct list)); new->data = data;
new->next = head;
return new; }

struct list * list_insert(struct list *head, int data) { struct list *new = malloc(sizeof(struct list)); new->data = data;
new->next = head;
return new; }
Memory allocation
sizeof operator gets the size of a type

Void list_delete(struct list *head) {
/* Write code for freeing all the nodes on the list and */

Freeing memory

List entry at 0x7b6517d0 has data 38 List entry at 0x7b6517c0 has data 36 List entry at 0x7b6517b0 has data 34 List entry at 0x7b6517a0 has data 32 List entry at 0x7b651790 has data 30 List entry at 0x7b651780 has data 28 List entry at 0x7b651770 has data 26 List entry at 0x7b651760 has data 24 List entry at 0x7b651750 has data 22 List entry at 0x7b651740 has data 20 List entry at 0x7b651730 has data 18 List entry at 0x7b651720 has data 16 List entry at 0x7b651710 has data 14 List entry at 0x7b651700 has data 12 List entry at 0x7b6516f0 has data 10 List entry at 0x7b6516e0 has data 8 List entry at 0x7b6516d0 has data 6 List entry at 0x7b6516c0 has data 4 List entry at 0x7b6516b0 has data 2 List entry at 0x7b6516a0 has data 0

Why did we have to use the extra to_delete variable?

 Function pointers
 Code in multiple files
 Linking to external libraries
 Preprocessor macros
 Some modifiers: static, const, volatile, extern
 Ternary operator, variable-argument functions (e.g., printf)

 C is a very low level language. You can address memory directly.
 We saw a lot of great features of C
 We saw a lot of ways you can shoot yourself in
the foot with C
 You will need to know/learn C for this class.

int main() {
char w[strlen(“C
programming”)];
strcpy(w,”C programming”); printf(“%s\n”, w);

int main() {
char w[strlen(“C
programming”)];
strcpy(w,”C programming”);
strlen returns the length of printf(“%s\n”, w);
return 0; }
the string not including the null character, so we end up
writing a null byte outside the bounds of w.

C Libraries

string.h: Common String/Array Methods
■ One the most useful libraries available to you
■ Important usage details
regarding arguments:
■ prefixes: str -> strings, mem -> arbitrary
memory blocks.
■ ensure that all strings are ‘/0’ terminated!
■ ensure that dest is large enough to store
■ ensure that src actually contains n bytes!
■ ensure that src/dest don’t overlap!

string.h: Common String/Array Methods
■ Copying:
■ void* memcpy (void* dest, void* src, size_t n): copy n bytes of
src into dest, return dest
■ char* strcpy(char* dest, char* src): copy src string into dest,
return dest
■ Concatenation:
■ char * strcat (char * dest, char* src): append copy of src to end
of dest, return dest
■ Comparison:
■ int strcmp (char * str1, char * str2): compare str1, str2 by
character (based on ASCII value of each character, then string length), return comparison result
str1 < str2: -1, str1 == str2: 0, str1 > str2: 1

string.h: Common String/Array Methods (Continued)
■ Searching:
■ char* strstr (char * str1, char * str2): return pointer
to first occurrence of str2 in str1, else NULL
■ char* strtok (char * str, char * delimiters): tokenize
str according to delimiter characters provided in delimiters, return the next token per successive stroke call, using str = NULL
■ size_t strlen ( const char * str ): returns length of the
string (up to, but not including the ‘\0’ character)
■ void * memset (void* ptr, int val, size_t n ): set first
n bytes of memory block addressed by ptr to val (use this for setting bytes only; don’t use to set int arrays or anything else!)

stdlib.h: General Purpose Functions
■ Dynamic memory allocation: ■ malloc, calloc, free
■ String conversion:
■ int atoi(char* str): parse string into integral value (return 0 if not parsed)
■ System Calls:
■ void exit(int status): terminate calling process, return status to parent process
■ void abort(): aborts process abnormally

程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com