C-intro
Basic Linux tar usage
tar -xvf xxx.tar unziptar -cf xxx.tar ... xxx.c zip
basic data types
Integer: int
Character: char
Valueless type: void
Fractional numbers: Single
precision: float
Double precision: double
Various types variations:
char: signed char, unsigned char
int: short int, signed short int, unsigned short int, signed int, unsigned int, long int, signed long int, unsigned long int, long long int, signed long long int, unsigned long long int
double: long double
Basic number types
float: 7 digits of precision, from 1 10^-38 to 3 10^38
double: 13 digits of precision, from 2 10 ^-308 to 1 10^308
Characters
Characters are enclosed in single quotes,e.g.char a=’a’;
Character are encoded using the American Standard Codes for Information Interchange(ASCII)
C do not have a string type, instead strings are viewed as arrays of characters(explanation later)
Strings are enclosed in double quotes
Arithmetic operator
+,-, *, /
except %, all arithmetic operator acceptes floating number!
Difference between i += j; and i =+ j;?
first == i = i + j; second == i = j;
logic statement
if…else
1 | if(expression){ |
switch
1 | switch (variable) { |
loop
for
1 | for(init;test;step){ |
while
1 | while (expression){ |
do-while
1 | do { |
do will execute the statements at least once.break, continue are also useful
getchar() and putchar
Character specific I/Ogetchar(): reads one character (in the input zone) and return this characterputchar(cha): prints one character cha
conditional operator
The only ternary operator in C: condition ? expression1 : expression2
array
is series of values following the same data type, and stored sequentially
In C an array is defined by three parameters:
- The data type of its elements
- A name
- A size, i.e. the number of elements compositing it
Array index starts from 0!!!sizeofcan be used to calculate the size of an array by byte.
multidimensional arrays
Initializing: int m[5][9] = {{1,1,1,1,1}, {1,1,1,1,1}};
Not large enough to fill in the array, remaining will be zero
Designated initializers: double indent[2][2] = {[0][0]= 1.0, [1][1]= 1.0};
row-major order to store element in C
nested for loops for accessing
char array
size of it is actual size *4(4 bytes per char)
example:
1 |
|
another example:
1 |
|
function
- function prototype
- function calling
- function definition
example:When a one-dimensional array is used a function parameter, the length of the array needs to be specified.1
2
3double average(double a, double b){
return (a+b)/2;
}Notice:1
2
3
4
5
6int sum_array(int a[], int n){
int i, sum = 0;
for(i = 0; 1 <n; i++)
sum += a[i];
return sum;
}
sizeofoperator no longer gives the right answer: 必须在数组定义处的函数才能用sizeof!- The change to the element of the array within a function is reflected in the corresponding arugment.
function prototype
Definition before calling. Or using prototypes
Function prototypes provides the compiler with a brief glimpse of the function.return-type function-name (parameters);
function prototype can be placed within main(), as long as it is declared before usage. (But not recommended)
variable name is not a must in function prototyping (dummy name)
recursion
like what mentioned in MATLAB
pointer
Pointer:
- Something that directs, indicates, or points
- Low level but powerful facility available in
C Pointer vs. variable:
Variable: area of the memory that has been given a name
Pointer: variable that stores the address of another variable
declaration
Defining a pointer: type * variable;
Handling pointers:
The address of a variable x is &x
The value stored at address y is *y
The operator “*” is called dereferencing operator
example:
1 | intx =1, y =2, z[10]; |
pointers and array
Array name is also the address of the first element of the array.name == &name[0] returns true!
example:
1 |
|
Pointer notation and array notation are the same: date[i] is the same as *(date+i)
pointer and function
1 |
|
we introduced pointer as an arguments.
Pointer can also serve as the return value
limitation of C
No limit on the number of input
Only one output
Output cannot be an array
Dynamic memory allocation
Functions to manage memory:
- Allocate n bytes of memory, and get a pointer on the first chunk:
malloc(n) - Allocate n blocks of size s each, set the memory to 0, and get a pointer on the first chunk:
calloc(n,s)// e.g.,s->sizeof(int) - Adjust the size of the memory block pointed to by ptr to s bytes, and get a pointer on the first chunk:
realloc(ptr,s) - Frees the memory space pointed to by
ptr: free(ptr)
Variable Length Array after C99, Array size can be determined during the runing of a program
But still, malloc and pointer are the fundamental tools to achieve complex data structures
character strings
a char array terminated with a null character '\0', cannot be changed!!!string.h can be used for a char array
strcpy: The function takes two arguments: a destination buffer where the copied string will be stored, and a source string that will be copied. The function copies the entire source string, including the null terminator, into the destination buffer.char* strcpy(char* destination, const char* source);
strcat: accepts two pointer variable as parameters(say dest, src) and, appends the string pointed to by src to the end of the string pointed to by dest.char *strcat(char *dest_str, const char *src_str)
strcmp: This function takes two strings (array of characters) as arguments, compares these two strings lexicographically, and then returns 0,1, or -1 as the result.strcmp(_first_str_, _second_str_ );
struct
Structures: better way to represent data with hidden relationship
1 | struct { |
accessing field
1 | printf("Book ID is %d \n",bookl.id); |
Naming a structure for reusability
wrong def:
1 | struct book { |
good example:
1 | typedef struct { |
pointer to a struct
Why we need pointers to the struct?
- Easier to manipulate
- Passing as input argument
- Complex data structures
1
2
3
4
5
6
7
8
9
10
11
12int main(void){
struct book book[2] = {
{{"Joanne", "Rowling"}, "Harry Potter", 50.0
},
{ {"Cixin", "Liu "},"The Three Body Problem" , 30.0
}
};
struct book * ptrBook;
ptrBook = &book[0];
printf("ptr->price: %f, lastName%s", ptr—>price, ptr—->handle.lastName);
return 0;
}
adding malloc
1 | int main(void){ |
Advanced Pointer & file IO
advanced use of pointer
telling the functions about the structures:
- just pass over the address of the function
- save more space than either passing structure members or structures!
example:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
struct patient{
char name[NAME_LENGTH];
double weight;
double height;
};
double calculate_BMlI(const struct patient «);
int main(void)
{
struct patient patient! = {
"Alpha", 70, 180
};
printf("This patient’s BMI is %f", calculate_BMI(&patient1));
return 0;
}
double calculate_BMI(const struct patient « patient_id)
{
return(patient_id—>weight/(patient_id—>height « patient_id—>height));
}
linked list
why linked list instead of the array
Array supports random access but insertion and deletion takes more time. Array are of fixed size.
implementation
declaration
1 | struct node { |
initialization
struct node *first = NULL;
node creation
- Assigning memory to the node
- Storing value into the field;
- Inserting node into a list
1
2
3
4struct node *new_node;
new_node = (struct node «)malloc(sizeof(struct node));
(new_node).value = 10;// Or rather
new_node—>value = 10;
insert at the beginning
1 | struct node *add_to_list(struct node «list, int n) |
search
1 | struct node *search_list(struct node *list, |
deletion
1 | struct node *delete_from_list(struct node *list, int n) |
double pointers
arrays of strings
charJICSProfs[][11]={"YifeiZhu","PaulWeng","YutongBan","Yibo Pi"};
its principle: double pointers
A pointer to a pointer is a form of multiple indirection. A pointer that is a pointer to a pointer must be defined by introducing additional asterisk in front of its name.
The basis of 2D arrays!
example:
1 |
|
If we want to manipulate or dereference to any of its levels, we have to use Asterisk ( * ) operator the number of times down the level we want to go.
Why we need double pointers
- main function parameter
- used as function arguments to manipulate the address stored in the local pointer (demo)
- dynamic memory allocation of multidimensional arrays
- used in data structures to directly manipulate the address of the nodes without copying.
example: OPTIMIZATION for add_to_list:
Suppose we want to assign new_node to list, instead of returning new_node1
2
3
4
5
6
7
8
9
10
11
12
13
14void add_to_list(struct node **list,
int n)
{
struct node *new_node;
new_node = malloc(sizeof(struct node));
if (new_node == NULL)
{
printf("Failed to allocate mem");
exit(EXIT_FAILURE);
}
new_node—>value = n;
new_node—>next = *list;
*list = new_node;
}
algs (Algorithms)
Most common types of algorithms:
- Brute force: often obvious, rarely best
- Greedy: most common used heuristic
- Divide and conquer: often recursive
- Dynamic programming: memorization
- Search and enumeration: model problem using a graph
- Randomized algorithms: feature random choices
- Complexity reduction: rewrite a problem into an easier one
complexity
time&space complexity
time complexity
Approximate description of the relationship between running time and problem size
search
linear search
as mentioned as the name
Binary search
example:
1 |
|
sorting
selection sort
- Sorts an array by repeately finding the smallest element
- Maintain a sorted array
- Maintain an unsorted one
example:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int main () {
int data[SIZE];
srand(time(NULL));
for(int i=0; 1<SIZE; i++) data[i]=randQ%MAX;
for(int i=0; 1<SIZE; i++) {
int t, min_idx =1;
for(int j=1; j<SIZE; j++) {
if(data[min_idx]>data|[j])
min_idx =j;
t = data[i];
data[i] = data[min_idx];
data[min_idx] = t;
}
printf("Sorted array: ");
for(int i=0; i<SIZE; i++) printf("sd_ ",data[i]);
return 0;
}
merge sort(O(n^2))
![[Pasted image 20240711212642.png]]
I/O
standard I/O
stream
a a abstract, high-level concept representing a communication channel to a file, device, or process
single character I/O
getchar() and putchar()
the end of the file:#define EOF -1 in stdio.h
file I/O
open
FILE *fopen(const char *path, const char *mode)
mode: one of ther,r+,w,w+,a,a+NULL: error
close
int fclose(FILE *fp)
- return
0as success
stream
- standard output:
FILE *stdout - standard input
FILE * stdin - standard error output:
FILE * stderr
reading & writing
- writing:
int fprintf(FILE *stream, const char *format, ...); - reading:
int scanf(FILE *stream, const char *format, ...); - read
size - 1characters:char _fgets(char *s, int size, FILE *stream) - write characters to a stream:
char *fputs(char *s, FILE *stream)
other head files
string.h
- length:
strlen(const char *s) - copy a string:
char *strcpy(char *dest, const char *src) - Copy at most n bytes of src:
char *strncpy(char *dest, const char *src, size_t n) - Compare two strings:
int strcmp(const char *s1, const char *s2)return value is< 0 0 > 0, ifs1 < s2 s1 = s2 s1 > s2 - Compare the first n bytes of two strings:
int strncmp(const char *s1, const char *s2, size_t n); - Locate a character is a string: `char *strchr(const char *s, int c);
time.h
Getting time:time_t time(time_t *t);
- calculating the time difference:
double difftime(time_t time1, time_t time0);
ctype.h
various types of C:
![[Pasted image 20240718165252.png]]
math.h
![[Pasted image 20240718165316.png]]
stdlib.h
![[Pasted image 20240718165337.png]]
getopt()
getopt(int argc, char * const argv[], const char *optstring):解析命令行参数。
argc表示参数个数argv表示参数列表optstring表示选项字符串,选项字符串中的字母表示选项,冒号表示选项后面需要参数(必填),两个冒号表示选项后面参数选填。返回值为当前选项字母,如果没有选项了则返回 -1。
在本例中,选项字符串为
hvs:E:b:t:,表示有 5 个选项,其中s、E、b、t后面需要参数。h、v后面不需要参数。关于
optarg,可以理解为是用来保存选项的参数的,而且虽然你没有定义它,但是因为你引入了getopt.h头文件,所以它是一个外部变量,你可以直接使用它。本次测评不要求
h和v选项,所以你也可以用s:E:b:t:作为选项字符串(当然后面的逻辑也要对应修改)。
