Programowanie Proceduralne Struktury Bożena Woźna-Szcześniak bwozna@gmail.com Jan Długosz University, Poland Wykład 10
Co dziś będzie: Definiowanie struktury Deklarowanie zmiennych bȩda cych strukturami Operator wyboru składowej Definiowanie struktury i nadawanie nazwy typu przy pomocy instrukcji typedef Deklarowanie zmiennych bȩda cych strukturami poła czone z inicjalizacja Wskaźniki do struktur
Struktura dla dat - przykład #include <stdio.h> struct Date { int y; short m; short d; ; int main(void) { struct Date sylwek; sylwek.y = 2009; sylwek.m = 5; sylwek.d = 4; printf("%2hd-%2hd-%04d\n", sylwek.d, sylwek.m, sylwek.y); return 0; [bw@wozna w08]$./data 4-5-2009
Instrukcja typedef #include <stdio.h> typedef struct { int y; short m; short d; Date; int main(void) { Date nowyrok; nowyrok.y = 2009; nowyrok.m = 5; nowyrok.d = 4; printf("%2hd-%2hd-%4d\n", nowyrok.d, nowyrok.m, nowyrok.y); return 0;
Instrukcja typedef #include <stdio.h> typedef struct { int y; short m; short d; Date; int main(void) { Date sylwek = {2005, 12, 31; printf("%02hd-%02hd-%04d\n", sylwek.d, sylwek.m, sylwek.y); return 0;
Operator wyboru składowej #include <stdio.h> #include <stdlib.h> typedef struct { int y; short m; short d; Date; int main(void) { Date* sylwek = calloc(1, sizeof(date)); // *sylwek.y = 2009; niepoprawne (*sylwek).y = 2009; poprawne sylwek->y = 2009; sylwek->m = 5; sylwek->d = 4; printf("%02hd-%2hd-%4d\n", sylwek->d, sylwek->m, sylwek->y); free(sylwek); return 0;
Program 1 #include <stdio.h> typedef struct { int y; short m; short d; Date; void init(date* date, int y, int m, int d); void show(date date); int main(void) { Date sylwek; init(&sylwek, 2006, 12, 7); show(sylwek); return 0;
Program 1 void init(date* date, int y, int m, int d) { date->y = y; date->m = m; date->d = d; void show(date date) { printf("%02hd-%02hd-%4d\n", date.d, date.m, date.y);
Program 2 #include <stdio.h> #include <stdlib.h> typedef struct { int y; short m; short d; Date; void init(date* date, int y, int m, int d); void show(date date); int main(void) { Date* sylwek = calloc(1, sizeof(date)); init(sylwek, 2006, 12, 7); show(*sylwek); return 0;
Program 2 void init(date* date, int y, int m, int d) { date->y = y; // (*date).y=y; date->m = m; date->d = d; void show(date date) { printf("%02hd-%02hd-%4d\n", date.d, date.m, date.y);
Program 1 #include <stdio.h> typedef struct { int y; short m; short d; Date; #define MAX_LEN 32 typedef struct { char name[max_len]; Date birthday; Person; void showdate(date const* date); void showperson(person const* person); int main(void) { Person ms = {"Jan Kowalski", {1987, 4, 19; showperson(&ms); return 0;
Program 1 void showperson(person const* person) { printf("%s ", person->name); showdate(&person->birthday); void showdate(date const* date) { printf("%02hd-%02hd-%04d\n", date->d, date->m, date->y);
Program 2 #include <stdio.h> #include <string.h> typedef struct { int y; short m; short d; Date; #define MAX_LEN 32 typedef struct { char name[max_len]; Date birthday; Person; void initdate(date* date, int y, int m, int d); void showdate(date const* date); void initperson(person*, char* name, int y, int m, int d); void showperson(person const* person);
Program 2 void initdate(date* date, int y, int m, int d) { date->y = y; date->m = m; date->d = d; void showdate(date const* date) { printf("%02hd-%02hd-%04d\n", date->d, date->m, date->y); void showperson(person const* person) { printf("%s ", person->name); showdate(&person->birthday); void initperson(person* person, char* name, int y, int m, int d) { strncpy(person->name, name, MAX_LEN); person->name[max_len - 1] = \0 ; initdate(&person->birthday, y, m, d);
Program 2 int main(int) { Person ms; initperson(&ms, "Maria Sharapova", 1987, 4, 19); showperson(&ms); return 0;
Program 1 #include <stdio.h> #include <string.h> #include <ctype.h> typedef struct { char* word; int count; Key; Key keytab[] = { {"auto", 0, {"break", 0, {"case", 0, {"char", 0, {"const", 0, {"continue", 0, {"default", 0, {"do", 0, {"double", 0, {"else", 0, {"enum", 0, {"extern", 0, {"float", 0, {"for", 0, {"goto", 0, {"if", 0, {"int", 0, {"long", 0, {"register", 0, {"return", 0, {"short", 0, {"signed", 0, {"sizeof", 0, {"static", 0, {"struct", 0, {"switch", 0, {"typedef", 0, {"union", 0, {"unsigned", 0, {"void", 0, {"volatile", 0, {"while", 0 ; int getword(char*, int); int binsearch(key const*, char const*, int); #define MAXWORD 100
Program 1 int getword(char* word, int lim) { char* w = word; int c; while (isspace(c = getc(stdin))) { if (c!= EOF) { *w++ = c; if (!isalpha(c)) { *w = \0 ; return c; for (; --lim > 0; ++w) { if (!isalnum(*w = getc(stdin))) { ungetc(*w, stdin); break; *w = \0 ; return 0;
Program 1 int binsearch(key const* tab, char const* word, int n) { int left = 0, right = n - 1; while (left <= right) { int mid = (left + right) / 2; int cond = strcmp(word, tab[mid].word); if (cond < 0) { right = mid - 1; else if (cond > 0) { left = mid + 1; else { return mid; return -1;
Program 1 int main(void) { int n; char word[maxword]; int const nkeys = sizeof(keytab) / sizeof(keytab[0]); while (getword(word, MAXWORD)!= EOF) { if (isalpha(word[0])) { if ((n = binsearch(keytab, word, nkeys)) >= 0) { ++keytab[n].count; // ++*(keytab + n).count; for (n = 0; n < nkeys; ++n) { if (keytab[n].count > 0) printf("%4d %s\n", keytab[n].count, keytab[n].word); printf("\n"); return 0;
Do przetwarzania argumentów (parsowania) linii poleceń służy funkcja getopt_long(), która korzysta zarówno z krótkich, jak i długich opcji. Jej prototyp znajduje się w pliku getopt.h: #define _GNU_SOURCE int getopt_long(int argc, const char *argv[], const char *shoropts, const struct option *longopts, int *longindex); argc - to liczba określajaca ilość argumentów listy, argv - jest tablica wskaźników do zaków o rozmiarze argc. Elementy tej tablicy wskazuja elementy listy argumentów, shortopts - wskaźnik na łańcuch znaków zawierajacy poprawne krótkie opcje (wszystkie jednoliterowe); po opcji wymagajacej argumentu występuje dwukropek, longopts jest to wskaźnik na tablicę specjalnych struktur struct option przechowujacej długie opcje.
Struktura struct option sturct option { const char *nazwa; int ma_argument; int *flagi; int zwroc; Aby określić dostępne długie opcje, musimy skonstruować tablicę elementów takich struktur jak powyżej. Każdy taki element odpowiada jednej długiej opcji i ma cztery pola. nazwa jest nazwa długiej opcjii (łanńcuch znaków pozbawiony 2 myślników, tj. help, a nie help). Drugie pole ma wartość 1 jeżeli opcja pobiera argument, 0 w przeciwnym wypadku. Trzecie pole ma wartość NULL, a czwarte to stała znakowa określajaca krótka opcję powiazaną z długa. Ostatni element tablicy powinien być wypełniony samymi zerami (jest to tzw. terminator ).
Program 2 #include <stdio.h> #include <stdlib.h> #include <getopt.h> void print_usage (char const* program_name, int exit_code) { printf("usage: %s options [ inputfile... ]\n", program_name); printf(" -h --help Display this usage information.\n"); printf(" -o --output filename Write output to file.\n"); printf(" -v --verbose Print verbose messages.\n"); exit (exit_code);
Program 2 int main (int argc, char* argv[]) { const char* const short_opts = "ho:v"; const struct option long_opts[] = { {"help", 0, NULL, h, {"output", 1, NULL, o, {"verbose", 0, NULL, v, {NULL, 0, NULL, 0 ; const char* output_filename = NULL; int verbose = 0, next_option; do { next_option = getopt_long(argc,argv,short_opts,long_opts,null); switch (next_option) { case h : print_usage (argv[0], 0); case o : output_filename = optarg; break; case v : verbose = 1; break; case? : print_usage(argv[0], 1); case -1: break; default: abort(); // switch while (next_option!= -1); if (verbose){ for (int i = optind; i < argc; ++i) printf ("Argument: %s\n", argv[i]); // Tu program główny return 0;