מבוא למדעי המחשב
תרגול 7: הגדרת טיפוסים, מבנים, מצביעים לפונקציות ופונקציות גנריות
תודה מיוחדת לאייל דיין על מצגות התרגול
1
הגדרת טיפוס - typedef
typedef existing-type new-type;
typdef int bool;
bool isLegal; // equal to: int isLegal;
תודה מיוחדת לאייל דיין על מצגות התרגול
2
מבנים
תודה מיוחדת לאייל דיין על מצגות התרגול
3
מבנים - Structures
struct struct-name {
type1 field1-name;
type2 field2-name;
…
};
struct struct-name var-name;
תודה מיוחדת לאייל דיין על מצגות התרגול
4
מבנים – Structures – דוגמא
struct Point {
int x;
int y;
};
int main() {
struct Point p1;
p1.x = 100;
p1.y = 200;
printf("(%d, %d)\n", p1.x, p1.y);
return 0;
}
תודה מיוחדת לאייל דיין על מצגות התרגול
5
Output:
(100, 200)
מבנים - Structures
תודה מיוחדת לאייל דיין על מצגות התרגול
6
מבנים - Structures
struct Point {
int x, y;
};
void main () {
struct Point p1 = {1,2};
struct Point p2;
scanf("%d%d", &p2.x, &p2.y);
printf("p1: {x:%d, y:%d}\n", p1.x, p1.y);
printf("p2: {x:%d, y:%d}\n", p2.x, p2.y);
p2 = p1;
printf("p1: {x:%d, y:%d}\n", p1.x, p1.y);
printf("p2: {x:%d, y:%d}\n", p2.x, p2.y);
}
תודה מיוחדת לאייל דיין על מצגות התרגול
7
Output:
3 4
p1: {x:1, y:2}
p2: {x:3, y:4}
p1: {x:1, y:2}
p2: {x:1, y:2}
מבנים - Structures
typedef struct struct-name struct-name;
struct-name var-name;
תודה מיוחדת לאייל דיין על מצגות התרגול
8
מבנים - Structures
typedef struct {
type1 field1-name;
type2 field2-name;
…
} struct-name;
struct-name var-name;
תודה מיוחדת לאייל דיין על מצגות התרגול
9
מבנים - Structures
int main() {
Line l;
scanf("%d%d%d%d", &l.p1.x, &l.p1.y, &l.p2.x, &l.p2.y);
l.len = sqrt(pow(l.p1.x-l.p2.x, 2) + pow(l.p1.y-l.p2.y, 2));
printf("The line length is: %.2f\n", l.len);
}
תודה מיוחדת לאייל דיין על מצגות התרגול
10
Output:
0 0 3 4
The line length is: 5.00
typedef struct {
Point p1,p2;
double len;
} Line;
typedef struct {
int x,y;
} Point;
מערך מבנים
Line lines[10];
lines[i].p1.x = val;
val = lines[i].p2.y;
תודה מיוחדת לאייל דיין על מצגות התרגול
11
מצביע למבנה
Point p;
Point* ptr = &p;
(*ptr).x = val;
val = (*ptr).x;
ptr->x = val;
val = ptr->x;
תודה מיוחדת לאייל דיין על מצגות התרגול
12
העברת מבנה לפונקציה
תודה מיוחדת לאייל דיין על מצגות התרגול
13
העברת מבנה לפונקציה
#include <stdio.h>
typedef struct {
int x;
int* p;
int arr[1];
} Simple;
void printSimple(const Simple* s) {
printf("s.x: %d\n", s->x);
printf("*(s.p): %d\n", *(s->p));
printf("s.arr[0]: %d\n", s->arr[0]);
}
תודה מיוחדת לאייל דיין על מצגות התרגול
14
arr[0] |
x |
arr |
p |
העברת מבנה לפונקציה
void update(Simple s) {
s.x = 10;
*(s.p) = 20;
s.arr[0] = 30;
}
void realUpdate(Simple* s) {
s->x = 100;
*(s->p) = 200;
s->arr[0] = 300;
}
תודה מיוחדת לאייל דיין על מצגות התרגול
15
העברת מבנה לפונקציה
void main() {
Simple s;
s.x = 1;
int local = 2;
s.p = &local;
s.arr[0] = 3;
printSimple(&s);
update(s);
printSimple(&s);
realUpdate(&s);
printSimple(&s);
}
תודה מיוחדת לאייל דיין על מצגות התרגול
16
Output:
s.x: 1
*(s.p): 2
s.arr[0]: 3
s.x: 1
*(s.p): 20
s.arr[0]: 3
s.x: 100
*(s.p): 200
s.arr[0]: 300
מבנים - תרגיל
תודה מיוחדת לאייל דיין על מצגות התרגול
17
מבנים - תרגיל
struct SEmployee {
char job[30];
int salary;
int seniority;
};
typedef struct SEmployee Employee_t;
void addEmployee(Employee_t employees[], int size, int* currentAmount);
void printList(Employee_t employees[], int currentAmount);
תודה מיוחדת לאייל דיין על מצגות התרגול
18
מבנים - תרגיל
#define SIZE 10
int main() {
char choice;
Employee_t employees[SIZE];
int currentAmount = 0;
do {
printf(…); /* here we print the menu */
scanf(" %c", &choice);
switch(choice) {
case '1':
addEmployee(employees, SIZE, ¤tAmount);
break;
case '2':
printList(employees, currentAmount);
break;
}
} while (choice != '0');
}
תודה מיוחדת לאייל דיין על מצגות התרגול
19
מבנים - תרגיל
void addEmployee(Employee_t employees[], int size, int* currentAmount) {
int insertingIndex = *currentAmount;
if (insertingIndex >= size) {
printf("Error! Too many employees.\n");
return;
}
printf("Enter job: ");
scanf(" %[^\n]", employees[insertingIndex].job);
printf("Enter salary: ");
scanf("%d", &employees[insertingIndex].salary);
printf("Enter seniority: ");
scanf("%d", &employees[insertingIndex].seniority);
(*currentAmount)++;
}
תודה מיוחדת לאייל דיין על מצגות התרגול
20
מבנים - תרגיל
void printList(Employee_t employees[], int currentAmount) {
for (int i = 0; i < currentAmount; ++i) {
printf("Job: %s, ", employees[i].job);
printf("Salary: %d, ", employees[i].salary);
printf("Seniority: %d\n", employees[i].seniority);
}
}
תודה מיוחדת לאייל דיין על מצגות התרגול
21
רשימה מקושרת
תודה מיוחדת לאייל דיין על מצגות התרגול
22
רשימה מקושרת
תודה מיוחדת לאייל דיין על מצגות התרגול
23
char name[12];
char id[10];
student_t *next;
char name[12];
char id[10];
student_t *next;
char name[12];
char id[10];
student_t *next;
main(){
student_t* head;
}
NULL
רשימה מקושרת
#include <string.h>
struct SStudent {
char name[12];
struct SStudent* next;
};
typedef struct SStudent Student_t;
תודה מיוחדת לאייל דיין על מצגות התרגול
24
רשימה מקושרת
#include <stdio.h>
void main() {
Student_t student1, student2, student3;
student1.name = "Nadav Doron";
student2.name = "Reut Asraf";
student3.name = "Lidor Elias";
student1.next = &student2;
student2.next = &student3;
student3.next = NULL;
printf("%s\n", student1.name);
printf("%s\n", student1.next->name);
printf("%s\n", student1.next->next->name);
}
תודה מיוחדת לאייל דיין על מצגות התרגול
25
Output:
Nadav Doron
Reut Asraf
Lidor Elias
רשימה מקושרת
#include <stdio.h>
void main() {
/* creating structs and assigning their fields
just like the previous slide */
Student_t* current = &student1;
while (current != NULL) {
printf("%s\n", current->name);
current = current->next;
}
}
תודה מיוחדת לאייל דיין על מצגות התרגול
26
Output:
Nadav Doron
Reut Asraf
Lidor Elias
מצביעים לפונקציות
תודה מיוחדת לאייל דיין על מצגות התרגול
27
מערכים ומצביעים (תזכורת)
תודה מיוחדת לאייל דיין על מצגות התרגול
28
מערך
type a[4];
type* b = a;
a[i]
b[i]
תודה מיוחדת לאייל דיין על מצגות התרגול
29
memory of a | |||
| | | |
a |
b |
פונקציה (תזכורת)
return-type function-name (type arg-name, …) {
statement;
}
return-type function-name (type, …);
תודה מיוחדת לאייל דיין על מצגות התרגול
30
פונקציה
תודה מיוחדת לאייל דיין על מצגות התרגול
31
פונקציה
type f(int x) {
…
}
type (*g)(int) = f;
f(x);
g(x);
תודה מיוחדת לאייל דיין על מצגות התרגול
32
f |
g |
code of f … … … |
מצביע לפונקציה
תודה מיוחדת לאייל דיין על מצגות התרגול
33
מצביע לפונקציה
return-type function-name (type, …);
return-type (*function-name-ptr) (type, …);
תודה מיוחדת לאייל דיין על מצגות התרגול
34
דוגמה
int max(int x, int y) {
if (x > y) {
return x;
} else {
return y;
}
}
תודה מיוחדת לאייל דיין על מצגות התרגול
35
int min(int x, int y) {
if (x < y) {
return x;
} else {
return y;
}
}
#include <stdio.h>
void main() {
int x;
int (*f)(int,int);
f = min;
x = f(1,2);
printf("%d\n", x);
f = max;
x = f(1,2);
printf("%d\n", x);
}
Output:
1
2
מצביע גנרי
void* p;
תודה מיוחדת לאייל דיין על מצגות התרגול
36
פונקציה גנרית
תודה מיוחדת לאייל דיין על מצגות התרגול
37
void print_int(int* p) {
printf("%d\n", *p);
}
void print_int(void* p) {
printf("%d\n", *(int*)p);
}
void print_string(char* p) {
printf("%s\n", p);
}
void print_char(char* p) {
printf("%c\n", *p);
}
void print_char(void* p) {
printf("%c\n", *(char*)p);
}
void print_string(void* p) {
printf("%s\n", (char*)p);
}
פונקציה גנרית
תודה מיוחדת לאייל דיין על מצגות התרגול
38
void print_int(int* p) {
printf("%d\n", *p);
}
void print_int(void* p) {
printf("%d\n", *(int*)p);
}
void print_string(char* p) {
printf("%s\n", p);
}
void print_char(char* p) {
printf("%c\n", *p);
}
void print_char(void* p) {
printf("%c\n", *(char*)p);
}
void print_string(void* p) {
printf("%s\n", (char*)p);
}
פונקציה גנרית
תודה מיוחדת לאייל דיין על מצגות התרגול
39
void main() {
char c = 'A';
int x = 250;
char s[] = "hello";
generic_print(&c, 2, print_char);
generic_print(&x, 5, print_int);
generic_print(s, 7, print_string);
}
void generic_print(void* p, int n, void(*print)(void*)) {
for (int i = 0; i < n; i++) {
print(p);
}
}
Output:
A
A
250
250
250
250
250
hello
hello
hello
hello
hello
hello
hello