Uploaded by Jeff Pollock

Final Exam Review

advertisement
CS 265
Final Exam Review
1
Final Exam
•
The Final Exam is scheduled for Monday, June 10, 2024, 10:3012:30, in 3675MK room 1054-1055.
•
The exam will be given online via Bb Learn.
You must be physically present in class to take the exam.
•
Format of the exam will be similar to the midterm.
2
Final Exam Topics
•
•
•
•
•
•
•
•
C Fundamentals
Pointers
Strings and Arrays
Command line arguments
Dynamic memory
Declarations
Structures, Unions, and Enumerations
Linked Lists
3
C vs other programming languages
•
C is a compiled language that compiles to machine code
•
C is a procedural language
•
C is a low-level programming language
– Closer to the HWD and the OS
4
C Compiler - Under the hood
There are four steps:
1. Pre-processing
2. Compiling - translating code to assembly code
3. Assembling – translating assembly code to machine code
4. Linking
5
Compiling vs Linking
a1.c
machine code
but not an executable
#include <stdio.h>
int main {
user_function1 ();
user_function2();
}
compile
a1.o
machine code
complete executable
a2.c
int user_function1()
{
…
}
compile
a2.o
compile
a3.o
link
a3.c
int user_function2()
{
…
}
/usr/include/stdio.h
…
printf()
…
Header file
for precompiled
library
/usr/lib/libc.a
6
a.out
char vs int Data Types in C
designed to hold a single
ASCII char, not Unicode
a char can hold 256 ( 28 )
different numbers
(there are some variations based on OS and compiler)
7
Assignment
An assignment is both a statement and an operator that evaluates to
the value of the assignment
•
This assigns 3 to a and, in addition, it evaluates to 3
a = 3
•
This assignment sets all variables to 0 and evaluates to 0
a = b = c = 0
•
It evaluates from right to left. It is equivalent to
a = (b = (c = 0))
•
This is valid C
if (a=b=c=0) {..}
•
The semantics of the assignment are different from Java / Python
8
Weakly-typed and statically-typed
counts digits, white space,
others
main()
{
int c, i, nwhite, nother;
int ndigit[10];
nwhite = nother = 0;
while ((c = getchar()) != EOF) {
if (c >= ′0′ && c <= ′9′)
++ndigit[c-′0′];
else if (c == ′ ′ ¦¦ c == ′\n′ ¦¦ c == ′\t′)
++nwhite;
else
++nother;
}
Statically typed
• You must declare variables before using them (unlike Python)
• You must declare a datatype for them (unlike Python)
Weakly typed
• C is not too particular about comparing the values of different
data types (unlike Java/Python)
9
Arrays
•
Define an array of 10 integers
int a[10];
•
Can be initialized at declaration
int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9} ;
int a[] = { 121, 17, 2, 88, -273 } ;
•
Access the array using indexes 0,… 9
a[0], a[1], … a[9]
10
Strings
•
Strings are arrays of characters ending with ‘\0’ (null)
Define a string as an array using characters
char name[10] = {‘d’, ‘i’, ‘m’, ‘i’, ‘t’, ‘r’,
‘a’, ‘\0’};
•
•
or, define a string array using double quotes “”
char name[10] = “Dimitra”;
•
Access the array elements using indexes 0,… 9, e.g.,
name[0], name[1], … name[9]
11
Functions
•
Functions are defined as
return-type function-name(parameter declarations, if any)
{
declarations
statements
}
•
•
•
Return types can be any data type or void (no return value)
In C, there are two ways to pass parameters
Call by value
– Any changes made to a parameter inside a function are gone when the
function completes
•
Call by reference
– Any changes made to a parameter inside a function persist even after the
function completes
12
Character data type
•
•
When a character appears in a computation, C uses its
integer value.
Consider the following examples, which assume the ASCII
character set:
char ch;
int i;
i = 'a';
ch = 65;
ch = ch + 1;
ch++;
/* i is now 97
*/
/* ch is now 'A' */
/* ch is now 'B' */
/* ch is now 'C' */
13
Precedence and Associativity of Operators
This table lists the
precedence and
associativity of C
operators.
Operators are
listed top to
bottom, in
descending
precedence.
14
https://en.cppreference.com/w/c/language/operator_precedence
Compound Assignment
•
•
•
•
The compound assignment operators (e.g., +=) are widely
used in C programs.
When using the compound assignment operators, be
careful not to switch the two characters that make up the
operator.
Although i =+ j will compile, it is equivalent to i = (+j),
which merely copies the value of j into i.
v += e isn’t always “equivalent” to v = v + e due to
operator precedence. For example:
i *= j + k isn’t the same as i = i * j + k.
Be careful when using += not to confuse it with =+
15
Increment and Decrement Operators
•
Two of the most common operations on a variable are
“incrementing” (adding 1) and “decrementing” (subtracting 1):
i = i + 1;
j = j - 1;
•
•
C provides special ++ (increment) and -- (decrement) operators.
The ++ operator adds 1 to its operand. The -- operator subtracts 1.
•
The increment and decrement operators are tricky to use:
– They can be used as prefix operators (++i and –-i) or postfix operators
(i++ and i--).
– They have side effects: they modify the values of their operands.
16
Increment and Decrement Operators
•
•
Evaluating the expression ++i (a “pre-increment”) yields i + 1
and—as a side effect—increments i:
i = 1;
printf("i is %d\n", ++i);
/* prints "i is 2" */
printf("i is %d\n", i);
/* prints "i is 2" */
Evaluating the expression i++ (a “post-increment”) produces the
result i, but causes i to be incremented afterwards:
i = 1;
printf("i is %d\n", i++);
/* prints "i is 1" */
printf("i is %d\n", i);
/* prints "i is 2" */
17
Increment and Decrement Operators
•
++i means “increment i immediately,” while i++ means
“use the old value of i for now, but increment i later.”
•
How much later? The C standard doesn’t specify a precise
time, but it’s safe to assume that i will be incremented
before the next statement is executed.
18
If statement
•
Typical form
if (expression) {
statements1
}
else {
statements2
}
•
Ternary form
expr1
?
expr2
:
expr3
Instead of
if (a < b)
{ c = a; }
else
{ c = b; }
Use
c = (a < b) ? a : b;
19
Switch statement
switch (expression) {
case const-expr :
statements;
break; /* optional */
case const-expr :
statements;
break; /* optional */
default:
statements;
}
20
For loop
for (expr1; expr2;
statement
expr3)
Valid for loops in C:
int i;
for (i=0; i< 10; i++) { …}
for( ; ; ) {
printf("This loop will run forever.\n");
}
for (int i=0; i< 10; i++) { …}
21
While Loops
while (expression) {
statements;
}
do
statements;
while (expression);
22
Loop Control Statements
break
• Terminates the loop or switch statement and transfers execution
to the statement immediately following the loop or switch.
continue:
•
Causes the loop to skip the remainder of its body and immediately
retest its condition prior to reiterating.
goto
•
Transfers control to the labeled statement.
if (expression) { goto error; }
…
error: printf(“This is an error”);
23
Pointer Variables
•
•
Addresses can be stored in special pointer variables
When we store the address of a variable i in the pointer
variable p, we say that p “points to” i.
24
Address and Redirection Operators
*p
unary operator * is the value of what the pointer p points to
&i
unary operator & is the address of variable i
25
Pointers – how to declare
Variables
int *p;
char *p;
void *p;
a pointer to a memory location for an integer
a pointer to a memory location for a char
a generic pointer
i.e., a pointer to any location
i.e., a pointer to an undefined data type
Note
int *p;
*p
as a declaration it is a mnemonic for pointer
it says that *p (where p points to) is an int
anywhere else *p it is the value of where p points to
26
Pointer arithmetic
The value of pointers are memory addresses, thus numbers, so we can do
arithmetic. There are four arithmetic operators that can be used in pointers
++
-+
-
•
Move the pointer to the next object (move one byte, if char *p, two
bytes if short *p)
p = p + 1;
•
or
p++;
Advance the pointer by 4 “objects”
p = p + 4;
27
Functions – Call by value
swap
void swap(int x, int y)
{
int temp;
/* WRONG */
temp = x;
x = y;
y = temp;
}
Before calling swap(x,y) the values are x=1 y=2
After calling swap(x,y) the values are x=1, y=2
28
Functions – call by reference
swap
void swap(int *px, int *py)
{
int temp;
/* interchange *px and *py */
temp = *px;
*px = *py;
*py = temp;
}
Before calling swap(&x,&y) the values are x=1 y=2
After calling swap(&x,&y) the values are x=2 y=1
29
Pointers and Arrays
•
•
•
In C there is a strong relationship between pointers and arrays
Any operation that involves array subscripting can use pointers
The declaration int a[10] defines and array
a
•
•
a[0]
a[1]
a[2]
a[9]
If we declare a pointer that points to the beginning of the array
int *p;
p = &a[0];
Then a[i] is the same as *(p+i) and &a[i] is the same as p+i
a
a[0]
a[1]
a[2]
a[9]
The name of an array is a pointer!
p
p+1
(p+1 points to the next object, not next byte)
30
Strings
•
Strings can be defined as character arrays
char date[10];
char date[] = "June 14";
•
Strings can be defined as pointers
char *date;
char *date = "June 14";
Thanks to the close relationship between arrays
and pointers, either version can be used as a string
31
Command Line Arguments
•
When main has command line arguments it is defined using
int main(int argc, char *argv[])
{
…
}
where
argc
argv
is the “argument count”, the number of arguments
is the “argument vector”, an array of pointers to the
argv[0]
arguments (stored as strings)
points to the name of the program
argv[1]
argv[argc-1]
argv[argc]
point to the remaining arguments
is always a null pointer
32
Memory Allocation Functions
<stdlib.h>
void *malloc(size_t size)
Allocates a block of memory but doesn’t initialize it
void *calloc(size_t nmemb, size_t size);
Allocates a block of memory and clears it
void *realloc(void *ptr, size_t size);
Resizes a previously allocated block of memory
void free(void *ptr);
Releases the memory pointed to by the pointer ptr
33
Function Stack Call
void f(int a, int b)
{
int x;
}
void main()
{
f(1,2);
printf("hello world");
}
•
•
•
•
•
•
•
main function calls f() with arguments a and b
f function stack frame is created below the main function frame
The arguments to f are stored in reverse order (first b then a)
The returns address in the f() stack frame points to the next instruction address
after the function is executed and returned
Here, it points to the printf() instruction
Every function frame has a pointer to the previous frame
The local variable x is stored in the frame
34
C Structures
A struct (structure) is a collection of one or more variables,
possibly of different types, grouped together under a single
name for convenient handling
• A structure is a collection of related data
• A struct is an aggregate data type, allowing related data
elements to be accessed and assigned as a unit.
• It defines a user-defined data type
• It is similar to a table in a database
• It is a foundational component that allows you to build
more complex data structures, like linked lists, stacks,
trees, etc.
35
Defining Structure Variables
•
•
You can define a variable and its structure at the same time
Here is a declaration of two variables part1 and part2 as
structures:
struct {
int number;
char name[NAME_LEN+1];
int on_hand;
} part1, part2;
36
How are structures stored in memory
•
The members of a structure are stored in memory in the order in
which they’re declared
•
Appearance of part1
•
Assumptions:
– part1 is located at address 2000
– Integers occupy four bytes
– NAME_LEN has the value 25
– There are no gaps between the members
– There is no null character at the end
– There is no null pointer at the end
37
Operators on Structures – The . operator
struct {
int number;
char name[NAME_LEN+1];
int on_hand;
} part1;
•
To access the members, we use the . operator
part1.number
part1.name
part1.on_hand
38
Structures can be Nested
•
•
Nesting one structure inside another is often useful
Suppose that person_name is the following structure:
struct person_name {
char first[FIRST_NAME_LEN+1];
char middle_initial;
char last[LAST_NAME_LEN+1];
};
•
•
We can define a student as
struct student {
struct person_name name;
int id, age;
} student1;
Accessing student1’s first name requires two applications of the .
operator:
strcpy(student1.name.first, "Fred");
student1.name = {“Fred”, ’X’, “Astaire”};
39
Pointers to Structures
struct student s;
struct student *p = &s;
•
Pointers to structures are so frequently used that an
alternative notation is provided as a shorthand. If p is a
pointer to a structure, then
p->x
•
is equivalent to the expression
(*p).x
40
Unions
•
•
•
A union, like a structure, consists of one or more members,
possibly of different types
The compiler allocates only enough space for the largest of
the members, which overlay each other within this space
Assigning a new value to one member alters the values of
the other members as well
41
Enumerations
•
•
Enumerated data types are possible with the enum keyword. They
are freely interconvertible with integers.
Examples: deck of cards
enum {CLUBS, DIAMONDS, HEARTS, SPADES} s1, s2;
•
Can be defined with an enumeration tag
enum suit {CLUBS, DIAMONDS, HEARTS, SPADES};
enum suit s1, s2;
•
Or with a typedef
typedef enum {CLUBS, DIAMONDS, HEARTS, SPADES} Suit;
Suit s1, s2;
42
enum
#include <stdio.h>
enum day {SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY,
FRIDAY, SATURDAY};
int main()
{
enum day d = TUESDAY;
printf("The day number stored in d is %d", d);
return 0;
}
•
Output:
The day number stored in d is 2
43
Linked Lists
•
A linked list consists of a chain of structures (called nodes), with
each node containing a pointer to the next node in the chain:
NULL pointer
vs arrays
• More flexible
• More dynamic
• Not as fast
44
Defining a Node Type
•
To create a linked list
•
First, we need to define a structure that defines a single node
struct node {
int value;
/* data stored in the node */
struct node *next; /* pointer to the next node */
};
45
Inserting a Node at the Beginning of a Linked List
•
A function that inserts a node containing n into a linked list, which
is pointed to by list:
struct node *add_to_list(struct node *list, int n)
{
struct node *new_node;
}
new_node = malloc(sizeof(struct node));
if (new_node == NULL) {
printf("Error: malloc failed in add_to_list\n");
exit(EXIT_FAILURE);
}
new_node->value = n;
new_node->next = list;
return new_node;
46
Searching a Linked List
•
struct node *search_list(struct node *list, int n)
{
for (; list != NULL && list->value != n;
list = list->next)
;
return list;
}
Since list is NULL if we reach the end of the list, returning list is
correct even if we don’t find n.
47
Deleting a Node from a Linked List
struct node *delete_from_list(struct node *list, int n)
{
struct node *cur, *prev;
}
for (cur = list, prev = NULL;
cur != NULL && cur->value != n;
prev = cur, cur = cur->next)
;
if (cur == NULL)
return list;
/* n was not found */
if (prev == NULL)
list = list->next;
/* n is in the first node */
else
prev->next = cur->next; /* n is in some other node */
free(cur);
return list;
48
Properties of variables
•
Every variable in a C program has three properties:
– Storage duration
– Scope
– Linkage
49
Declaration Syntax and Examples
storage-class type-qualifier type-specifier function-specifier declarators;
A declaration with a storage class and three declarators:
A declaration with a type qualifier and initializer but no storage class:
50
Download