Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Extracted code

  • Loading branch information...
commit e18d6a3d43269857fdeb454fb6fc130fac62679c 1 parent 78a053d
@dogriffiths authored
Showing with 4,266 additions and 0 deletions.
  1. +12 −0 chapter11/Page 11/code_code_frag_at_end.c
  2. +31 −0 chapter11/Page 12/code.c
  3. +32 −0 chapter11/Page 13/code.c
  4. +17 −0 chapter11/Page 14/code.c
  5. +17 −0 chapter11/Page 16/code.c
  6. +37 −0 chapter11/Page 17/code.c
  7. +4 −0 chapter11/Page 20/code_frag_at_start.c
  8. +28 −0 chapter11/Page 22/code.c
  9. +20 −0 chapter11/Page 27/code_frag_at_end.c
  10. +35 −0 chapter11/Page 28/code.c
  11. +35 −0 chapter11/Page 30/code.c
  12. +30 −0 chapter11/Page 31/code.c
  13. +14 −0 chapter11/Page 4/code.c
  14. +7 −0 chapter11/Page 5/code.c
  15. +3 −0  chapter11/Page 6/code.c
  16. +28 −0 chapter11/Page 8/code.c
  17. +26 −0 chapter12/Page 10/code.c
  18. +29 −0 chapter12/Page 15/code.c
  19. +24 −0 chapter12/Page 16/code.c
  20. +24 −0 chapter12/Page 18/code.c
  21. +34 −0 chapter12/Page 6/code.c
  22. +22 −0 chapter12/Page 7/code.c
  23. +30 −0 chapter12/Page 9/code.c
  24. +32 −0 chapter2.5/Page 47/code.c
  25. +9 −0 chapter2.5/Page 48/code.c
  26. +28 −0 chapter3/Page 14/code-quotes.c
  27. +30 −0 chapter3/Page 21/code.c
  28. +30 −0 chapter3/Page 23/code_extras_on_end.c
  29. +30 −0 chapter3/Page 24/code_extras_on_end.c
  30. +18 −0 chapter3/Page 3/code.c
  31. +16 −0 chapter3/Page 32/code_with_quotes.c
  32. +18 −0 chapter3/Page 4/code.c
  33. +29 −0 chapter3/Page 40/code_with_quotes.c
  34. +16 −0 chapter3/Page 41/gpsdata.data.c
  35. +15 −0 chapter3/Page 42/gpsdata.data.c
  36. +37 −0 chapter3/Page 46/code.c
  37. 0  chapter3/Page 48/code.c
  38. +28 −0 chapter3/Page 9/gpsdata.csv
  39. +8 −0 chapter4/Page 174/code.c
  40. +9 −0 chapter4/Page 178/code.c
  41. +41 −0 chapter4/Page 18/code_multiple_progs.c
  42. +304 −0 chapter4/Page 191/code_lots_of_progs.c
  43. +69 −0 chapter4/Page 23/code_multiple_progs.c
  44. +164 −0 chapter4/Page 6/code_lots_of_progs.c
  45. +308 −0 chapter5/Page 218/code_lots_of_progs.c
  46. +242 −0 chapter5/Page 30/code_lots_of_progs.c
  47. +15 −0 chapter5/Page 38/code_includes_shell.c
  48. +598 −0 chapter6/Page 278/code_lots_of_progs.c
  49. +299 −0 chapter6/Page 28/code_lots_of_progs.c
  50. +1,224 −0 chapter7/Page 336/code_lots_of_progs.c
  51. +78 −0 chapter9/Page 438/code_lots_of_progs.c
  52. +8 −0 chapter9/Page 444/code.c
  53. +8 −0 chapter9/Page 446/code.c
  54. +8 −0 chapter9/Page 464/code.c
  55. +8 −0 chapter9/Page 466/code.c
View
12 chapter11/Page 11/code_code_frag_at_end.c
@@ -0,0 +1,12 @@
+ <s>bind (listener_d, (struct sockaddr *) &name, sizeof (name));</s>
+ if (bind (listener_d, (struct sockaddr *) &name, sizeof (name)) == -1)
+ error("Can't bind the port");
+ $ ./advice_server
+ Waiting for connection
+ ^C
+ $ ./advice_server
+ Can't bind the port: Address already in use
+ $
+ int reuse = 1;
+ if (setsockopt(listener_d, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(int)) == -1)
+ error("Can't set the reuse option on the socket");
View
31 chapter11/Page 12/code.c
@@ -0,0 +1,31 @@
+ <bytes read> = recv(<descriptor>, <buffer>, <bytes to read>, 0);
+ |---+---+---+---+---+---+---+---+---+---+---+---+----+----|
+ | W | h | o | ' | s | | t | h | e | r | e | ? | \r | \n |
+ |---+---+---+---+---+---+---+---+---+---+---+---+----+----|
+ int read_in(int d, char* buf, int buflen) {
+ int count = recv(d, buf, buflen, 0);
+ if (count > 1)
+ buf[count - 2] = '\0';
+ else
+ buf[0] = '\0';
+ return count;
+ }
+ char buf[255];
+ if (read_in(d, buf, sizeof(buf)) == -1) {
+ /* Handle the error */
+ }
+char* s = buf;
+ int slen = len;
+ int c = recv(socket, s, slen, 0);
+ while ((c > 0) && (s[c-1] != '\n')) {
+ s++; slen -= c;
+ c = recv(socket, s, slen, 0);
+ }
+ if (c < 0)
+ return c;
+ else if (c == 0)
+ buf[0] = '\0';
+ else
+ s[c-1]='\0';
+ return slen - len;
+ }
View
32 chapter11/Page 13/code.c
@@ -0,0 +1,32 @@
+ void error(char* msg)
+ {
+ fprintf(stderr, "%s: %s\n", msg, strerror(errno));
+ exit(1);
+ }
+ int open_listener_socket()
+ {
+ int s = socket(PF_INET, SOCK_STREAM, 0);
+ if (s == -1)
+ error("Can't open socket");
+ return s;
+ }
+ void bind_to_port(int socket, int port)
+ {
+ struct sockaddr_in name;
+ name.sin_family = PF_INET;
+ name.sin_port = (in_port_t)htons(30000);
+ name.sin_addr.s_addr = htonl(INADDR_ANY);
+ int reuse = 1;
+ if (setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(int)) == -1)
+ error("Can't set the reuse option on the socket");
+ int c = bind (socket, (struct sockaddr *) &name, sizeof (name));
+ if (c == -1)
+ error("Can't bind to socket");
+ }
+ int say(int socket, char* s)
+ {
+ int result = send(socket, s, strlen(s), 0);
+ if (result == -1)
+ fprintf(stderr, "%s: %s\n", "Error talking to the client", strerror(errno));
+ return result;
+ }
View
17 chapter11/Page 14/code.c
@@ -0,0 +1,17 @@
+ #include <stdio.h>
+ #include <string.h>
+ #include <errno.h>
+ #include <stdlib.h>
+ #include <sys/socket.h>
+ #include <arpa/inet.h>
+ #include <unistd.h>
+ #include <signal.h>
+ ....
+ int listener_d;
+ void handle_shutdown(int sig)
+ {
+ if (listener_d)
+ close(listener_d);
+ fprintf(stderr, "Bye!\n");
+ exit(0);
+ }
View
17 chapter11/Page 16/code.c
@@ -0,0 +1,17 @@
+ #include <stdio.h>
+ #include <string.h>
+ #include <errno.h>
+ #include <stdlib.h>
+ #include <sys/socket.h>
+ #include <arpa/inet.h>
+ #include <unistd.h>
+ #include <signal.h>
+ ....
+ int listener_d;
+ void handle_shutdown(int sig)
+ {
+ if (listener_d)
+ close(listener_d);
+ fprintf(stderr, "Bye!\n");
+ exit(0);
+ }
View
37 chapter11/Page 17/code.c
@@ -0,0 +1,37 @@
+ int main(int argc, char* argv[])
+ {
+ if (signal(SIGINT, handle_shutdown) == SIG_ERR)
+ error("Can't set the interrupt handler");
+ listener_d = open_listener_socket();
+ bind_to_port(listener_d, 30000);
+ if (listen(listener_d, 10) == -1)
+ error("Can't listen");
+ struct sockaddr_storage client_addr;
+ unsigned int address_size = sizeof client_addr;
+ puts("Waiting for connection");
+ char buf[255];
+ for(;;) {
+ int connect_d = accept(listener_d, (struct sockaddr *)&client_addr,
+ &address_size);
+ if (connect_d == -1)
+ error("Can't open secondary socket");
+ if (say(connect_d,
+ "Internet Knock-Knock Protocol Server\r\nVersion 1.0\r\nKnock! Knock!\r\n> ")
+ != -1) {
+ read_in(connect_d, buf, sizeof(buf));
+ if (strncasecmp("Who's there?", buf, 12))
+ say(connect_d, "You should say 'Who's there?'!");
+ else {
+ if (say(connect_d, "Oscar\r\n> ") != -1) {
+ read_in(connect_d, buf, sizeof(buf));
+ if (strncasecmp("Oscar who?", buf, 10))
+ say(connect_d, "You should say 'Oscar who?'!\r\n");
+ else
+ say(connect_d, "Oscar silly question, you get a silly answer\r\n");
+ }
+ }
+ }
+ close(connect_d);
+ }
+ return 0;
+ }
View
4 chapter11/Page 20/code_frag_at_start.c
@@ -0,0 +1,4 @@
+ close(connect_d);
+ close(listener_d);
+ Q: If I create a new process for each client, what happens if hundreds of clients connect? Will my machine create hundreds of processes?
+ A: Yes. If you think your server will get a lot of clients, you need to control how many processes you create. The child can signal you when it's finished with a client and you can use that to maintain a count of current child processes.
View
28 chapter11/Page 22/code.c
@@ -0,0 +1,28 @@
+ for(;;) {
+ int connect_d = accept(listener_d, (struct sockaddr *)&client_addr,
+ &address_size);
+ if (connect_d == -1)
+ error("Can't open secondary socket");
+ if (!fork()) {
+ close(listener_d);
+ if (say(connect_d,
+ "Internet Knock-Knock Protocol Server\r\nVersion 1.0\r\nKnock! Knock!\r\n> ")
+ != -1) {
+ read_in(connect_d, buf, sizeof(buf));
+ if (strncasecmp("Who's there?", buf, 12))
+ say(connect_d, "You should say 'Who's there?'!");
+ else {
+ if (say(connect_d, "Oscar\r\n> ") != -1) {
+ read_in(connect_d, buf, sizeof(buf));
+ if (strncasecmp("Oscar who?", buf, 10))
+ say(connect_d, "You should say 'Oscar who?'!\r\n");
+ else
+ say(connect_d, "Oscar silly question, you get a silly answer\r\n");
+ }
+ }
+ }
+ close(connect_d);
+ exit(0);
+ }
+ close(connect_d);
+ }
View
20 chapter11/Page 27/code_frag_at_end.c
@@ -0,0 +1,20 @@
+ |------------------+-----------------|
+ | Domain name | Address |
+ |------------------+-----------------|
+ | en.wikipedia.org | 91.198.174.225 |
+ | www.oreilly.com | 208.201.239.100 |
+ | www.oreilly.com | 208.201.239.101 |
+ | ... | ... |
+ |------------------+-----------------|
+ #include <netdb.h>
+ ...
+ struct addrinfo *res;
+ struct addrinfo hints;
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ getaddrinfo("www.oreilly.com", "80", &hints, &res);
+ int s = socket(res->ai_family, res->ai_socktype,
+ res->ai_protocol);
+ connect(s, res->ai_addr, res->ai_addrlen);
+ freeaddrinfo(res);
View
35 chapter11/Page 28/code.c
@@ -0,0 +1,35 @@
+ #include <stdio.h>
+ #include <string.h>
+ #include <errno.h>
+ #include <stdlib.h>
+ #include <sys/socket.h>
+ #include <arpa/inet.h>
+ #include <unistd.h>
+ #include <netdb.h>
+
+ void error(char* msg)
+ {
+ fprintf(stderr, "%s: %s\n", msg, strerror(errno));
+ exit(1);
+ }
+
+ int open_socket(char* host, char* port)
+ {
+ struct addrinfo *res;
+ struct addrinfo hints;
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ if (getaddrinfo(host, port, &hints, &res) == -1)
+ error("Can't resolve the address");
+ int d_sock = socket(res->ai_family, res->ai_socktype,
+ res->ai_protocol);
+ if (d_sock == -1)
+ error("Can't open socket");
+ int c = connect(d_sock, res->ai_addr, res->ai_addrlen);
+ freeaddrinfo(res);
+ if (c == -1)
+ error("Can't connect to socket");
+ return d_sock;
+ }
+
View
35 chapter11/Page 30/code.c
@@ -0,0 +1,35 @@
+ #include <stdio.h>
+ #include <string.h>
+ #include <errno.h>
+ #include <stdlib.h>
+ #include <sys/socket.h>
+ #include <arpa/inet.h>
+ #include <unistd.h>
+ #include <netdb.h>
+
+ void error(char* msg)
+ {
+ fprintf(stderr, "%s: %s\n", msg, strerror(errno));
+ exit(1);
+ }
+
+ int open_socket(char* host, char* port)
+ {
+ struct addrinfo *res;
+ struct addrinfo hints;
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ if (getaddrinfo(host, port, &hints, &res) == -1)
+ error("Can't resolve the address");
+ int d_sock = socket(res->ai_family, res->ai_socktype,
+ res->ai_protocol);
+ if (d_sock == -1)
+ error("Can't open socket");
+ int c = connect(d_sock, res->ai_addr, res->ai_addrlen);
+ freeaddrinfo(res);
+ if (c == -1)
+ error("Can't connect to socket");
+ return d_sock;
+ }
+
View
30 chapter11/Page 31/code.c
@@ -0,0 +1,30 @@
+ int say(int socket, char* s)
+ {
+ int result = send(socket, s, strlen(s), 0);
+ if (result == -1)
+ fprintf(stderr, "%s: %s\n", "Error talking to the server", strerror(errno));
+ return result;
+ }
+
+ int main(int argc, char* argv[])
+ {
+ int d_sock;
+ d_sock = open_socket("en.wikipedia.org", "80");
+ char buf[255];
+ sprintf(buf, "GET /wiki/%s http/1.1\r\n", argv[1]);
+ say(d_sock, buf);
+ say(d_sock, "Host: en.wikipedia.org\r\n\r\n");
+ char rec[256];
+ int bytesRcvd = recv(d_sock, rec, 255, 0);
+ while (bytesRcvd) {
+ if (bytesRcvd == -1)
+ error("Can't read from server");
+ rec[bytesRcvd] = '\0';
+ printf("%s", rec);
+ bytesRcvd = recv(d_sock, rec, 255, 0);
+ }
+ close(d_sock);
+ return 0;
+ }
+ "Host: en.wikipedia.org\r\n"
+ "\r\n"
View
14 chapter11/Page 4/code.c
@@ -0,0 +1,14 @@
+ #include <sys/socket.h>
+ ...
+ int listener_d = socket(PF_INET, SOCK_STREAM, 0);
+ if (listener_d == -1)
+ error("Can't open socket");
+ #include <arpa/inet.h>
+ ...
+ struct sockaddr_in name;
+ name.sin_family = PF_INET;
+ name.sin_port = (in_port_t)htons(30000);
+ name.sin_addr.s_addr = htonl(INADDR_ANY);
+ int c = bind (listener_d, (struct sockaddr *) &name, sizeof (name));
+ if (c == -1)
+ error("Can't bind to socket");
View
7 chapter11/Page 5/code.c
@@ -0,0 +1,7 @@
+ if (listen(listener_d, 10) == -1)
+ error("Can't listen");
+ struct sockaddr_storage client_addr;
+ unsigned int address_size = sizeof client_addr;
+ int connect_d = accept(listener_d, (struct sockaddr *)&client_addr, &address_size);
+ if (connect_d == -1)
+ error("Can't open secondary socket");
View
3  chapter11/Page 6/code.c
@@ -0,0 +1,3 @@
+ char* msg = "Internet Knock-Knock Protocol Server\r\nVersion 1.0\r\nKnock! Knock!\r\n> ";
+ if (send(connect_d, msg, strlen(msg), 0) == -1)
+ error("send");
View
28 chapter11/Page 8/code.c
@@ -0,0 +1,28 @@
+ int main(int argc, char* argv[])
+ {
+ char* advice[] = {
+ "Take smaller bites\r\n",
+ "Go for the tight jeans. No they do NOT make you look fat.\r\n",
+ "One word: inappropriate\r\n",
+ "Just for today, be honest. Tell your boss what you *really* think\r\n",
+ "You might want to rethink that haircut\r\n"
+ };
+ int listener_d = socket(PF_INET, SOCK_STREAM, 0);
+ struct sockaddr_in name;
+ name.sin_family = PF_INET;
+ name.sin_port = (in_port_t)htons(30000);
+ name.sin_addr.s_addr = htonl(INADDR_ANY);
+ bind (listener_d, (struct sockaddr *) &name, sizeof (name));
+ listen(listener_d, 10);
+ puts("Waiting for connection");
+ for (;;) {
+ struct sockaddr_storage client_addr;
+ unsigned int address_size = sizeof client_addr;
+ int connect_d = accept(listener_d, (struct sockaddr *)&client_addr, &address_size);
+ char *msg = advice[rand() % 5];
+ send(connect_d, msg, strlen(msg), 0);
+ close(connect_d);
+ }
+ return 0;
+ }
+ Check for errors
View
26 chapter12/Page 10/code.c
@@ -0,0 +1,26 @@
+ int beers = 2000000;
+ void* drink_lots()
+ {
+ int i;
+ for (i = 0; i < 100000; i++) {
+ beers = beers - 1;
+ }
+ return NULL;
+ }
+ int main()
+ {
+ pthread_t threads[20];
+ int t;
+ printf("%i bottles of beer on the wall\n%i bottles of beer\n", beers, beers);
+ for (t = 0; t < 20; t++) {
+ pthread_create(&threads[t], NULL, drink_lots, NULL);
+ }
+ void* result;
+ for (t = 0; t < 20; t++) {
+ pthread_join(threads[t], &result);
+ }
+ printf("There are now %i bottles of beer on the wall\n", beers);
+ return 0;
+ }
+ threads[t]
+ threads
View
29 chapter12/Page 15/code.c
@@ -0,0 +1,29 @@
+ void* do_stuff(void* param)
+ {
+ long thread_no = (long)param;
+ printf("Thread number %ld\n", thread_no);
+ return (void*)(thread_no + 1);
+ }
+
+ int main()
+ {
+ pthread_t threads[20];
+ long t;
+ for (t = 0; t < 3; t++) {
+ pthread_create(&threads[t], NULL, do_stuff, (void*)t);
+ }
+ void* result;
+ for (t = 0; t < 3; t++) {
+ pthread_join(threads[t], &result);
+ printf("Thread %ld returned %ld\n", t, (long)result);
+ }
+ return 0;
+ }
+ > ./param_test
+ Thread number 0
+ Thread 0 returned 1
+ Thread number 1
+ Thread number 2
+ Thread 1 returned 2
+ Thread 2 returned 3
+ >
View
24 chapter12/Page 16/code.c
@@ -0,0 +1,24 @@
+ pthread_mutex_t beers_lock = PTHREAD_MUTEX_INITIALIZER;
+ void* drink_lots()
+ {
+ int i;
+ pthread_mutex_lock(&beers_lock);
+ for (i = 0; i < 100000; i++) {
+ beers = beers - 1;
+ }
+ pthread_mutex_unlock(&beers_lock);
+ printf("beers = %i\n", beers);
+ return NULL;
+ }
+ pthread_mutex_t beers_lock = PTHREAD_MUTEX_INITIALIZER;
+ void* drink_lots()
+ {
+ int i;
+ for (i = 0; i < 100000; i++) {
+ pthread_mutex_lock(&beers_lock);
+ beers = beers - 1;
+ pthread_mutex_unlock(&beers_lock);
+ }
+ printf("beers = %i\n", beers);
+ return NULL;
+ }
View
24 chapter12/Page 18/code.c
@@ -0,0 +1,24 @@
+ pthread_mutex_t beers_lock = PTHREAD_MUTEX_INITIALIZER;
+ void* drink_lots()
+ {
+ int i;
+ pthread_mutex_lock(&beers_lock);
+ for (i = 0; i < 100000; i++) {
+ beers = beers - 1;
+ }
+ pthread_mutex_unlock(&beers_lock);
+ printf("beers = %i\n", beers);
+ return NULL;
+ }
+ pthread_mutex_t beers_lock = PTHREAD_MUTEX_INITIALIZER;
+ void* drink_lots()
+ {
+ int i;
+ for (i = 0; i < 100000; i++) {
+ pthread_mutex_lock(&beers_lock);
+ beers = beers - 1;
+ pthread_mutex_unlock(&beers_lock);
+ }
+ printf("beers = %i\n", beers);
+ return NULL;
+ }
View
34 chapter12/Page 6/code.c
@@ -0,0 +1,34 @@
+ void* does_not()
+ {
+ int i = 0;
+ for (i = 0; i < 5; i++) {
+ sleep(1);
+ puts("Does not!");
+ }
+ return NULL;
+ }
+ void* does_too()
+ {
+ int i = 0;
+ for (i = 0; i < 5; i++) {
+ sleep(1);
+ puts("Does too!");
+ }
+ return NULL;
+ }
+ +----------------------+
+ | |
+ | does_not() function |
+ /-+ |
+ +-----------------+ /----- | |
+ | | /----- +----------------------+
+ | +--
+ | Main program |
+ | |
+ | +--
+ +-----------------+ \--- +--------------------+
+ \---- | |
+ \--- | does_too() function|
+ \-+ |
+ | |
+ +--------------------+
View
22 chapter12/Page 7/code.c
@@ -0,0 +1,22 @@
+ #import <stdio.h>
+ #import <stdlib.h>
+ #include <string.h>
+ #include <unistd.h>
+ #include <errno.h>
+ #include <pthread.h>
+ void error(char* msg)
+ {
+ fprintf(stderr, "%s: %s\n", msg, strerror(errno));
+ exit(1);
+ }
+ pthread_t t0;
+ pthread_t t1;
+ if (pthread_create(&t0, NULL, does_not, NULL) == -1)
+ error("Can't create thread t0");
+ if (pthread_create(&t1, NULL, does_too, NULL) == -1)
+ error("Can't create thread t1");
+ void* result;
+ if (pthread_join(t0, &result) == -1)
+ error("Can't join thread t0");
+ if (pthread_join(t1, &result) == -1)
+ error("Can't join thread t1");
View
30 chapter12/Page 9/code.c
@@ -0,0 +1,30 @@
+ int beers = 2000000;
+ void* drink_lots()
+ {
+ int i;
+ for (i = 0; i < 100000; i++) {
+ beers = beers - 1;
+ }
+ return NULL;
+ }
+ int main()
+ {
+ pthread_t threads[20];
+ int t;
+ printf("%i bottles of beer on the wall\n%i bottles of beer\n", beers, beers);
+ for (t = 0; t < 20; t++) {
+ _________________(_______________, NULL, _______________, NULL);
+ }
+ void* result;
+ for (t = 0; t < 20; t++) {
+ ________________(threads[t], &result);
+ }
+ printf("There are now %i bottles of beer on the wall\n", beers);
+ return 0;
+ }
+ pthread_join
+ pthread_create
+ drink_lots
+ &threads[t]
+ threads[t]
+ threads
View
32 chapter2.5/Page 47/code.c
@@ -0,0 +1,32 @@
+ int main()
+ {
+ char search_for[80];
+ printf("Search for: ");
+ fgets(search_for, 80, stdin);
+ find_track();
+ return 0;
+ }
+ int main()
+ {
+ char search_for[80];
+ printf("Search for: ");
+ fgets(search_for, 80, stdin);
+ find_track(search_for);
+ return 0;
+ }
+ int main()
+ {
+ char search_for[80];
+ printf("Search for: ");
+ fgets(search_for, 79, stdin);
+ find_track(search_for);
+ return 0;
+ }
+ int main()
+ {
+ char search_for[80];
+ printf("Search for: ");
+ scanf(search_for, 80, stdin);
+ find_track(search_for);
+ return 0;
+ }
View
9 chapter2.5/Page 48/code.c
@@ -0,0 +1,9 @@
+ int main()
+ {
+ char search_for[80];
+ printf("Search for: ");
+ fgets(search_for, 80, stdin);
+ find_track(search_for);
+ return 0;
+ }
+ char *names_for_dog[] = {"Bowser", "Bonza", "Snodgrass"};
View
28 chapter3/Page 14/code-quotes.c
@@ -0,0 +1,28 @@
+ #include <stdio.h>
+
+ int main()
+ {
+ float latitude;
+ float longitude;
+ char info[80];
+ int started = 0;
+
+ puts("data=[");
+ while (scanf("%f,%f,%79[^\n]", &latitude, &longitude, info) == 3) {
+ if (started)
+ printf(",\n");
+ else
+ started = 1;
+ '''if ((latitude < -90.0) || (latitude > 90.0)) {'''
+ '''printf("Invalid latitude: %f\n", latitude);'''
+ '''return 2;'''
+ '''}'''
+ '''if ((longitude < -180.0) || (longitude > 180.0)) {'''
+ '''printf("Invalid longitude: %f\n", longitude);'''
+ '''return 2;'''
+ '''}'''
+ printf("{latitude: %f, longitude: %f, info: '%s'}", latitude, longitude, info);
+ }
+ puts("\n]");
+ return 0;
+ }
View
30 chapter3/Page 21/code.c
@@ -0,0 +1,30 @@
+ #include <stdio.h>
+
+ int main()
+ {
+ float latitude;
+ float longitude;
+ char info[80];
+ int started = 0;
+
+ puts("data=[");
+ while (scanf("%f,%f,%79[^\n]", &latitude, &longitude, info) == 3) {
+ if (started)
+ printf(",\n");
+ else
+ started = 1;
+ if ((latitude < -90.0) || (latitude > 90.0)) {
+ <s>printf("Invalid latitude: %f\n", latitude);</s>
+ '''fprintf(stderr, "Invalid latitude: %f\n", latitude);'''
+ return 2;
+ }
+ if ((longitude < -180.0) || (longitude > 180.0)) {
+ <s>printf(stderr, "Invalid longitude: %f\n", longitude);</s>
+ '''fprintf(stderr, "Invalid longitude: %f\n", longitude);'''
+ return 2;
+ }
+ printf("{latitude: %f, longitude: %f, info: '%s'}", latitude, longitude, info);
+ }
+ puts("\n]");
+ return 0;
+ }
View
30 chapter3/Page 23/code_extras_on_end.c
@@ -0,0 +1,30 @@
+ #include <stdio.h>
+
+ int main()
+ {
+ char word[10];
+ int i = 0;
+ while (scanf("%9s", word) == 1) {
+ i = i + 1;
+ if (i % 2)
+ fprintf(stdout, "%s\n", word);
+ else
+ fprintf(stderr, "%s\n", word);
+ }
+ return 0;
+ }
+ Run with:
+ secret_messages < secret.txt > message1.txt 2> message2.txt
+ ............................
+ ............................
+ ............................
+ ............................
+ ............................
+ ............................
+ ............................
+ ............................
+ ............................
+ ............................
+ ............................
+ ............................
+ ............................
View
30 chapter3/Page 24/code_extras_on_end.c
@@ -0,0 +1,30 @@
+ #include <stdio.h>
+
+ int main()
+ {
+ char word[10];
+ int i = 0;
+ while (scanf("%9s", word) == 1) {
+ i = i + 1;
+ if (i % 2)
+ fprintf(stdout, "%s\n", word);
+ else
+ fprintf(stderr, "%s\n", word);
+ }
+ return 0;
+ }
+ Run with:
+ secret_messages < secret.txt > message1.txt 2> message2.txt
+ THE
+ SUBMARINE
+ WILL
+ SURFACE
+ AT
+ NINE
+ PM
+ BUY
+ SIX
+ EGGS
+ AND
+ SOME
+ MILK
View
18 chapter3/Page 3/code.c
@@ -0,0 +1,18 @@
+ #include <stdio.h>
+ int main()
+ {
+ float latitude;
+ float longitude;
+ char info[80];
+ int started = ____;
+ puts("data=[");
+ while (scanf("%f,%f,%79[^\n]", __________, __________, __________) == 3) {
+ if (started)
+ printf(",\n");
+ else
+ started = ____;
+ printf("{latitude: %f, longitude: %f, info: '%s'}", _________, ________, _______);
+ }
+ puts("\n]");
+ return 0;
+ }
View
16 chapter3/Page 32/code_with_quotes.c
@@ -0,0 +1,16 @@
+ #include <stdio.h>
+
+ int main()
+ {
+ float latitude;
+ float longitude;
+ char info[80];
+ while (scanf("%f,%f,%79[^\n]", '''&latitude''', '''&longitude''', '''info''') == 3)
+ if (('''latitude''' > '''26''') '''&&''' ('''latitude''' < '''34'''))
+ if (('''longitude''' > '''-76''') '''&&''' ('''longitude''' < '''-64'''))
+ printf("%f,%f,%s\n", '''latitude''', '''longitude''', '''info''');
+ return 0;
+ }
+ ||
+ ||
+ &info
View
18 chapter3/Page 4/code.c
@@ -0,0 +1,18 @@
+ #include <stdio.h>
+ int main()
+ {
+ float latitude;
+ float longitude;
+ char info[80];
+ int started = '''0''';
+ puts("data=[");
+ while (scanf("%f,%f,%79[^\n]", '''&latitude''', '''&longitude''', '''info''') == 3) {
+ if (started)
+ printf(",\n");
+ else
+ started = '''1''';
+ printf("{latitude: %f, longitude: %f, info: '%s'}", '''latitude''', '''longitude''', '''info''');
+ }
+ puts("\n]");
+ return 0;
+ }
View
29 chapter3/Page 40/code_with_quotes.c
@@ -0,0 +1,29 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+
+ int main(int argc, char* args[])
+ {
+ char line[80];
+ if (argc != 6) {
+ fprintf(stderr, "You need to give 5 arguments\n");
+ return 1;
+ }
+ FILE* in = fopen("gpsdata.data", "r");
+ FILE* file1 = fopen(args[2], "w");
+ FILE* file2 = fopen(args[4], "w");
+ FILE* file3 = fopen(args[5], "w");
+ while (fscanf(in, "%79[^\n]\n", line) == 1) {
+ if (strstr(line, args[1]))
+ fprintf(file1, "%s\n", line);
+ else if (strstr(line, args[3]))
+ fprintf(file2, "%s\n", line);
+ else
+ fprintf(file3, "%s\n", line);
+ }
+ fclose(file1);
+ fclose(file2);
+ fclose(file3);
+ return 0;
+ }
+ 5
View
16 chapter3/Page 41/gpsdata.data.c
@@ -0,0 +1,16 @@
+ 42.363400,-71.098465,Speed = 21,Type="Mermaid"
+ 42.363327,-71.097588,Speed = 23,Type="UFO"
+ 42.363255,-71.096710,Speed = 17,Type="Disappearance"
+ 42.363182,-71.095833,Speed = 22,Type="UFO"
+ 42.363110,-71.094955,Speed = 14,Type="Goatsucker"
+ 42.363037,-71.094078,Speed = 16,Type="Disappearance"
+ 42.362965,-71.093201,Speed = 18,Type="UFO"
+ 42.362892,-71.092323,Speed = 22,Type="Giant octopus"
+ 42.362820,-71.091446,Speed = 17,Type="Disappearance"
+ 42.362747,-71.090569,Speed = 23,Type="UFO"
+ 42.362675,-71.089691,Speed = 14,Type="Elvis"
+ 42.362602,-71.088814,Speed = 19,Type="UFO"
+ 42.362530,-71.087936,Speed = 16,Type="Disappearance"
+ 42.362457,-71.087059,Speed = 16,Type="Disappearance"
+ 42.362385,-71.086182,Speed = 21,Type="Yeti"
+ categorize UFO aliens.csv Elvis elvises.csv the_rest.csv
View
15 chapter3/Page 42/gpsdata.data.c
@@ -0,0 +1,15 @@
+ 42.363327,-71.097588,Speed = 23,Type="UFO"
+ 42.363182,-71.095833,Speed = 22,Type="UFO"
+ 42.362965,-71.093201,Speed = 18,Type="UFO"
+ 42.362747,-71.090569,Speed = 23,Type="UFO"
+ 42.362602,-71.088814,Speed = 19,Type="UFO"
+ 42.362675,-71.089691,Speed = 14,Type="Elvis"
+ 42.363400,-71.098465,Speed = 21,Type="Mermaid"
+ 42.363255,-71.096710,Speed = 17,Type="Disappearance"
+ 42.363110,-71.094955,Speed = 14,Type="Goatsucker"
+ 42.363037,-71.094078,Speed = 16,Type="Disappearance"
+ 42.362892,-71.092323,Speed = 22,Type="Giant octopus"
+ 42.362820,-71.091446,Speed = 17,Type="Disappearance"
+ 42.362530,-71.087936,Speed = 16,Type="Disappearance"
+ 42.362457,-71.087059,Speed = 16,Type="Disappearance"
+ 42.362385,-71.086182,Speed = 21,Type="Yeti"
View
37 chapter3/Page 46/code.c
@@ -0,0 +1,37 @@
+ #include <stdio.h>
+ #include <unistd.h>
+
+ int main(int argc, char* args[])
+ {
+ char* delivery = "";
+ int thick = 0;
+ int count = 0;
+ char ch;
+ while ((ch = getopt(argc, args, "d:t")) != EOF)
+ switch (ch) {
+ case 'd':
+ delivery = optarg;
+ break;
+ case 't':
+ thick = 1;
+ break;
+ default:
+ fprintf(stderr, "Unknown option: '%s'\n", optarg);
+ return 1;
+ }
+
+ argc -= optind;
+ args += optind;
+
+ if (thick)
+ puts("Thick crust.");
+
+ if (delivery[0])
+ printf("To be delivered %s.\n", delivery);
+
+ puts("Ingredients:");
+
+ for (count = 0; count < argc; count++)
+ puts(args[count]);
+ return 0;
+ }
View
0  chapter3/Page 48/code.c
No changes.
View
28 chapter3/Page 9/gpsdata.csv
@@ -0,0 +1,28 @@
+ 42.363400,-71.098465,Speed = 21
+ 42.363327,-71.097588,Speed = 23
+ 42.363255,-71.096710,Speed = 17
+ 42.363182,-71.095833,Speed = 22
+ 42.363110,-71.094955,Speed = 14
+ 42.363037,-71.094078,Speed = 16
+ 42.362965,-71.093201,Speed = 18
+ 42.362892,-71.092323,Speed = 22
+ 42.362820,-71.091446,Speed = 17
+ 42.362747,-71.090569,Speed = 23
+ 42.362675,-71.089691,Speed = 14
+ 42.362602,-71.088814,Speed = 19
+ 42.362530,-71.087936,Speed = 16
+ 42.362457,-71.087059,Speed = 16
+ 42.362385,-71.086182,Speed = 21
+ $ ./geo2json < gpsdata.csv
+ data=[
+ {latitude: 42.363400, longitude: -71.098465, info: 'Speed = 21'},
+ {latitude: 42.363327, longitude: -71.097588, info: 'Speed = 23'},
+ {latitude: 42.363255, longitude: -71.096710, info: 'Speed = 17'},
+ {latitude: 42.363182, longitude: -71.095833, info: 'Speed = 22'},
+ {latitude: 42.363110, longitude: -71.094955, info: 'Speed = 14'},
+ {latitude: 42.363037, longitude: -71.094078, info: 'Speed = 16'},
+ ...
+ ...
+ {latitude: 42.362385, longitude: -71.086182, info: 'Speed = 21'}
+ ]
+ $
View
8 chapter4/Page 174/code.c
@@ -0,0 +1,8 @@
+ void encrypt(char* message)
+ {
+ char c;
+ while (*message) {
+ *message = *message ^ 31;
+ message++;
+ }
+ }
View
9 chapter4/Page 178/code.c
@@ -0,0 +1,9 @@
+ #include "encrypt.h"
+ void encrypt(char* message)
+ {
+ char c;
+ while (*message) {
+ *message = *message ^ 31;
+ message++;
+ }
+ }
View
41 chapter4/Page 18/code_multiple_progs.c
@@ -0,0 +1,41 @@
+ #include <stdio.h>
+ +--------------------------------------------------+
+ | |
+ | |
+ +--------------------------------------------------+
+ printf("A day on Mercury is %f hours\n", day);
+ return 0;
+ }
+ float mercury_day_in_earth_days()
+ {
+ return 58.65;
+ }
+ int hours_in_an_earth_day()
+ {
+ return 24;
+ }
+ float mercury_day_in_earth_days();
+ int hours_in_an_earth_day();
+ int main()
+ {
+ float length_of_day = mercury_day_in_earth_days();
+ int hours = hours_in_an_earth_day();
+ float day = length_of_day * hours;
+ float mercury_day_in_earth_days();
+ int main()
+ {
+ float length_of_day = mercury_day_in_earth_days();
+ int hours = hours_in_an_earth_day();
+ float day = length_of_day * hours;
+ int main()
+ {
+ float length_of_day = mercury_day_in_earth_days();
+ int hours = hours_in_an_earth_day();
+ float day = length_of_day * hours;
+ float mercury_day_in_earth_days();
+ int hours_in_an_earth_day();
+ int main()
+ {
+ int length_of_day = mercury_day_in_earth_days();
+ int hours = hours_in_an_earth_day();
+ float day = length_of_day * hours;
View
304 chapter4/Page 191/code_lots_of_progs.c
@@ -0,0 +1,304 @@
+ /* Print out the catalog entry */
+ void catalog(const char* name, const char* species, int teeth, int age)
+ {
+ printf("%s is a %s with %i teeth. He is %i\n",
+ name, species, teeth, age);
+ }
+
+ /* Print the label for the tank */
+ void label(const char* name, const char* species, int teeth, int age)
+ {
+ printf("Name:%s\nSpecies:%s\n%i years old, %i teeth\n",
+ name, species, teeth, age);
+ }
+ int main()
+ {
+ catalog("Snappy", "Piranha", 69, 4);
+ label("Snappy", "Piranha", 69, 4);
+ return 0;
+ }
+ struct fish {
+ const char* name;
+ const char* species;
+ int teeth;
+ int age;
+ };
+ struct fish snappy = {"Snappy", "Piranha", 69, 4};
+ /* Print out the catalog entry */
+ void catalog(struct fish f)
+ {
+ ...
+ }
+
+ /* Print the label for the tank */
+ void label(struct fish f)
+ {
+ ...
+ }
+ struct fish snappy = {"Snappy", "Piranha", 69, 4};
+ catalog(snappy);
+ label(snappy);
+ struct fish snappy = {"Snappy", "piranha", 69, 4};
+ printf("Name = %s\n", snappy[0]);
+ $ gcc fish.c -o fish
+ fish.c: In function ��main��:
+ fish.c:12: error: subscripted value is neither array nor pointer
+ $
+ struct fish snappy = {"Snappy", "piranha", 69, 4};
+ printf("Name = %s\n", snappy.name);
+ $ gcc fish.c -o fish
+ $ ./fish
+ Name = Snappy
+ $
+ void catalog(struct fish f)
+ {
+ printf("%s is a %s with %i teeth. He is %i\n",
+ ___.________, ___.___________, ___.________, ___._______);
+ }
+
+ int main()
+ {
+ struct fish snappy = {"Snappy", "Piranha", 69, 4};
+ catalog(snappy);
+ /* We're skipping calling label for now */
+ return 0;
+ }
+ name
+ species
+ teeth
+ age
+ f
+ f
+ f
+ f
+ fish
+ fish
+ fish
+ fish
+ *
+ *
+ void catalog(struct fish f)
+ {
+ printf("%s is a %s with %i teeth. He is %i\n",
+ '''a'''.'''name''', '''a'''.'''species''', '''a'''.'''teeth''', '''a'''.'''age''');
+ }
+
+ int main()
+ {
+ struct fish snappy = {"Snappy", "Piranha", 69, 4};
+ catalog(snappy);
+ /* We're skipping calling label for now */
+ return 0;
+ }
+ fish
+ fish
+ fish
+ fish
+ *
+ *
+ $ make pool_puzzle && ./pool_puzzle
+ gcc pool_puzzle.c -o pool_puzzle
+ Snappy is a Piranha with 69 teeth. He is 4
+ Name:Snappy
+ Species:Piranha
+ 4 years old, 69 teeth
+ $
+ label(snappy);
+ catalog(snappy);
+ Q:So is a struct just an array?
+ A:No - but like an array it groups a number of pieces of data together.
+ Q:An array variable is just a pointer to the array. Is a struct variable a pointer to a struct?
+ A:No. A struct variable is a name for the struct itself.
+ Q:I know I don't have to, but ''could'' I use [0], [1],... to access the fields of a struct?
+ A:No - you can only access fields by name.
+ Q:Are structs like classes in other languages?
+ A:They are similar, but it's not so easy to add methods to structs.
+ struct fish {
+ const char* name;
+ const char* species;
+ int teeth;
+ int age;
+ };
+ struct fish snappy = {"Snappy", "Piranha", 69, 4};
+ |-------+----------+----+---|
+ | *name | *species | 69 | 4 |
+ |-------+----------+----+---|
+ "Snappy"
+ "Piranha"
+ struct fish snappy = {"Snappy", "Piranha", 69, 4};
+ struct fish gnasher = snappy;
+ |-------+----------+----+---|
+ | *name | *species | 69 | 4 |
+ |-------+----------+----+---|
+ |-------+----------+----+---|
+ | *name | *species | 69 | 4 |
+ |-------+----------+----+---|
+ "Snappy"
+ "Piranha"
+ struct preferences {
+ const char* food;
+ float exercise_hours;
+ };
+
+ struct fish {
+ const char* name;
+ const char* species;
+ int teeth;
+ int age;
+ struct preferences care;
+ };
+ struct fish snappy = {"Snappy", "Piranha", 69, 4, {"Meat", 7.5}};
+ printf("Snappy likes to eat %s", snappy.care.food);
+ printf("Snappy likes to exercise for %f hours", snappy.care.exercise_hours);
+ struct exercise {
+ const char* description;
+ float duration;
+ };
+
+ struct meal {
+ const char* ingredients;
+ float weight;
+ };
+
+ struct preferences {
+ struct meal food;
+ struct exercise exercise;
+ };
+
+ struct fish {
+ const char* name;
+ const char* species;
+ int teeth;
+ int age;
+ struct preferences care;
+ };
+ Name: Snappy
+ Species: Piranha
+ Food ingredients: meat
+ Food weight: 0.2 lbs
+ Exercise description: swim in the jacuzzi
+ Exercise duration 7.5 hours
+ struct fish snappy = _____________________________________________________
+ Name:Snappy
+ Species:Piranha
+ 4 years old, 69 teeth
+ Feed with 0.20 lbs of meat and allow to swim in the jacuzzi for 7.50 hours
+ void label(struct fish a)
+ {
+ printf("Name:%s\nSpecies:%s\n%i years old, %i teeth\n",
+ a.name, a.species, a.teeth, a.age);
+ printf("Feed with %2.2f lbs of %s and allow to %s for %2.2f hours\n",
+ __________________, _____________________,
+ _____________________, ____________________);
+ }
+ struct exercise {
+ const char* description;
+ float duration;
+ };
+
+ struct meal {
+ const char* ingredients;
+ float weight;
+ };
+
+ struct preferences {
+ struct meal food;
+ struct exercise exercise;
+ };
+
+ struct fish {
+ const char* name;
+ const char* species;
+ int teeth;
+ int age;
+ struct preferences care;
+ };
+ Name: Snappy
+ Species: Piranha
+ Food ingredients: meat
+ Food weight: 0.2 lbs
+ Exercise description: swim in the jacuzzi
+ Exercise duration 7.5 hours
+ struct fish snappy = ''{"Snappy", "Piranha", 69, 4, {{"meat", 0.2}, {"swim in the jacuzzi", 7.5}}};''
+ Name:Snappy
+ Species:Piranha
+ 4 years old, 69 teeth
+ Feed with 0.20 lbs of meat and allow to swim in the jacuzzi for 7.50 hours
+ void label(struct fish a)
+ {
+ printf("Name:%s\nSpecies:%s\n%i years old, %i teeth\n",
+ a.name, a.species, a.age, a.teeth);
+ printf("Feed with %2.2f lbs of %s and allow to %s for %2.2f hours\n",
+ ''a.care.food.weight'', ''a.care.food.ingredients'',
+ ''a.care.exercise.description'', ''a.care.exercise.duration);''
+ }
+ struct cell_phone {
+ int cell_no;
+ const char * wallpaper;
+ float minutes_of_charge;
+ };
+ ...
+ struct cell_phone p = {5557879, "sinatra.png", 1.35};
+ typedef struct cell_phone {
+ int cell_no;
+ const char * wallpaper;
+ float minutes_of_charge;
+ } phone;
+ ...
+ phone p = {5557879, "sinatra.png", 1.35};
+ typedef struct {
+ int cell_no;
+ const char * wallpaper;
+ float minutes_of_charge;
+ } '''phone''';
+ phone p = {5557879, "sinatra.png", 1.35};
+ #include <stdio.h>
+
+ _________ struct {
+ float tank_capacity;
+ int tank_psi;
+ const char* suit_material;
+ } ___________;
+
+ _________ struct scuba {
+ const char* name;
+ equipment kit;
+ } diver;
+
+ void badge(_____ d)
+ {
+ printf("Name: %s Tank: %2.2f(%i) Suit: %s\n",
+ d.name, d.kit.tank_capacity, d.kit.tank_psi, d.kit.suit_material);
+ }
+
+ int main()
+ {
+ _______ randy = {"Randy", {5.5, 3500, "Neoprene"}};
+ badge(randy);
+ return 0;
+ }
+ #include <stdio.h>
+
+ typedef struct {
+ float tank_capacity;
+ int tank_psi;
+ const char* suit_material;
+ } equipment;
+
+ typedef struct scuba {
+ const char* name;
+ equipment kit;
+ } diver;
+
+ void badge(diver d)
+ {
+ printf("Name: %s Tank: %2.2f(%i) Suit: %s\n",
+ d.name, d.kit.tank_capacity, d.kit.tank_psi, d.kit.suit_material);
+ }
+
+ int main()
+ {
+ diver randy = {"Randy", {5.5, 3500, "Neoprene"}};
+ badge(randy);
+ return 0;
+ }
View
69 chapter4/Page 23/code_multiple_progs.c
@@ -0,0 +1,69 @@
+ auto
+ if
+ break
+ int
+ case
+ long
+ char
+ register
+ continue
+ return
+ default
+ short
+ do
+ sizeof
+ double
+ static
+ else
+ struct
+ entry
+ switch
+ extern
+ typedef
+ float
+ union
+ for
+ unsigned
+ goto
+ while
+ enum
+ void
+ const
+ signed
+ volatile
+ Read a series of strings from the standard input and display and encrypted version on the standard output using XOR encryption.
+ Read the contents of a file and create an encrypted version using XOR encryption.
+ void encrypt(char* message)
+ {
+ char c;
+ while (*message) {
+ *message = *message ^ 17;
+ message++;
+ }
+ }
+ movq -24(%rbp), %rax
+ movzbl (%rax), %eax
+ movl %eax, %edx
+ 10010101 00100101 11010101 01011100 11001010 01100010 01100101
+ void encrypt(char* message);
+ #include "encrypt.h"
+ void encrypt(char* message)
+ {
+ char c;
+ while (*message) {
+ *message = *message ^ 17;
+ message++;
+ }
+ }
+ #include <stdio.h>
+ #include "encrypt.h"
+ int main()
+ {
+ char msg[80];
+ while (fgets(msg, 79, stdin)) {
+ encrypt(msg);
+ printf("%s", msg);
+ }
+ }
+ gcc message_hider.c encrypt.c -o message_hider
+ extern int passcode;
View
164 chapter4/Page 6/code_lots_of_progs.c
@@ -0,0 +1,164 @@
+ #include <stdio.h>
+ '''_______''' total = 0.0;
+ '''_______''' count = 0;
+ '''_______''' tax_percent = 6;
+ '''_______''' add_with_tax(float f)
+ {
+ '''_______''' tax_rate = 1 + tax_percent / 100'''____''';
+ total = total + (f * tax_rate);
+ count = count + 1;
+ return total;
+ }
+ int main()
+ {
+ '''________''' val;
+ printf("Price of item: ");
+ while (scanf("%f", &val) == 1) {
+ printf("Total so far: %.2f\n", add_with_tax(val));
+ printf("Price of item: ");
+ }
+ printf("\nFinal total: %.2f\n", total);
+ printf("Number of items: %i\n", count);
+ return 0;
+ }
+ #include <stdio.h>
+ '''float''' total = 0.0;
+ '''short''' count = 0;
+ '''short''' tax_percent = 6;
+ '''float''' add_with_tax(float f)
+ {
+ '''float''' tax_rate = 1 + tax_percent / 100'''.0''';
+ total = total + (f * tax_rate);
+ count = count + 1;
+ return total;
+ }
+ int main()
+ {
+ '''float''' val;
+ printf("Price of item: ");
+ while (scanf("%f", &val) == 1) {
+ printf("Total so far: %.2f\n", add_with_tax(val));
+ printf("Price of item: ");
+ }
+ printf("\nFinal total: %.2f\n", total);
+ printf("Number of items: %i\n", count);
+ return 0;
+ }
+ float tax_rate = 1 + tax_percent / 100.0;
+ 1 + tax_percent / 100;
+ #include <stdio.h>
+ #include <limits.h>
+ #include <float.h>
+ int main()
+ {
+ printf("The value of INT_MAX is %i\n", INT_MAX);
+ printf("The value of INT_MIN is %i\n", INT_MIN);
+ printf("An int takes %li bytes\n", sizeof(int));
+ printf("The value of FLT_MAX is %f\n", FLT_MAX);
+ printf("The value of FLT_MIN is %.50f\n", FLT_MIN);
+ printf("A float takes %li bytes\n", sizeof(float));
+ return 0;
+ }
+ The value of INT_MAX is 2147483647
+ The value of INT_MIN is -2147483648
+ An int takes 4 bytes
+ The value of FLT_MAX is 340282346638528859811704183484516925440.000000
+ The value of FLT_MIN is 0.00000000000000000000000000000000000001175494350822
+ A float takes 4 bytes
+ Q: Why are data typs different on different operating systems? Wouldn't it be less confusing to make them all the same?
+ A: C uses different data types of different operating systems and processors because it allows it to make the most out of the hardware.
+ Q: In what way?
+ A: When C was first created, most machines were 8 bit. Now most machines are 32 or 64 bit. Because C doesn't specify the exact size of its data-types, it's been able to adapt over time. And as newer machines are created C will be able to make the most of them as well.
+ Q: What does 8 bit? and 64 bit actually mean?
+ A: Technically the bit size of a computer can refer to several things - such as the size of its CPU instructions, or the amount of data the CPU can read from memory. The bit-size is really the favored size of numbers that the computer can deal with.
+ Q: So what does that have to do with the size of ints and doubles?
+ A: If a computer is optimized best to work with 32 bit numbers, it makes sense if the basic data-type - the int - is set at 32 bits.
+ Q: I understand how whole numbers like ints work, but how are floats and numbers stored? How does the computer represent a number with a decimal point?
+ A: It's complicated. Most computers used a standard published by the IEEE (http://tinyurl.com/6defkv6).
+ Q: Do I really need to understand how floating point numbers work?
+ A: No. The vast majority of developers use floats and doubles without worrying about the details.
+ #include <stdio.h>
+ float total = 0.0;
+ short count = 0;
+ '''/* This is 6%. Which is a lot less than my agent takes...*/'''
+ short tax_percent = 6;
+ int main()
+ {
+ '''/* Hey - I was up for a movie with Val Kilmer */'''
+ float val;
+ printf("Price of item: ");
+ while (scanf("%f", &val) == 1) {
+ printf("Total so far: %.2f\n", add_with_tax(val));
+ printf("Price of item: ");
+ }
+ printf("\nFinal total: %.2f\n", total);
+ printf("Number of items: %i\n", count);
+ return 0;
+ }
+ float add_with_tax(float f)
+ {
+ float tax_rate = 1 + tax_percent / 100.0;
+ '''/* And what about the tip? Voice lessons ain't free */'''
+ total = total + (f * tax_rate);
+ count = count + 1;
+ return total;
+ }
+ $ gcc totalling_broken.c -o totalling_broken && ./totalling_broken
+ totalling_broken.c: In function ��main��:
+ totalling_broken.c:14: warning: format ��%.2f�� expects type ��double��, but argument 2 has type ��int��
+ totalling_broken.c: At top level:
+ totalling_broken.c:23: error: conflicting types for ��add_with_tax��
+ totalling_broken.c:14: error: previous implicit declaration of ��add_with_tax�� was here
+ printf("Total so far: %.2f\n", add_with_tax(val));
+ float add_with_tax(float f)
+ int do_whatever(){...}
+ float do_something_fantastic(int awesome_level) {...}
+ int do_stuff() {
+ do_something_fantastic(11);
+ }
+ float ping() {
+ ...
+ pong();
+ ...
+ }
+ float pong() {
+ ...
+ ping();
+ ...
+ }
+ float add_with_tax();
+ float do_something_fantastic();
+ double awesomeness_2_dot_0();
+ int stinky_pete();
+ char make_maguerita(int count);
+ #include <stdio.h>
+ float add_with_tax(float f);
+ #include <stdio.h>
+ #include "totaller.h"
+ > gcc totaller.c -o totaller
+ > ./totalling_fixed
+ Price of item: 1.23
+ Total so far: 1.30
+ Price of item: 4.57
+ Total so far: 6.15
+ Price of item: 11.92
+ Total so far: 18.78
+ Price of item: ^D
+ Final total: 18.78
+ Number of items: 3
+ Q: So I don't need to have declarations for int functions?
+ A; Not necessaarily - unless you are sharing code. We'll see more about this soon.
+ Q: I'm confused. You talk about the compiler ''precompiling''? Why does the ''compiler'' do that?
+ A: Strictly speaking the compiler just does the compilation step - it converts the C source code into assembly code. But in a looser sense, all of the stages that convert the C source code into the final executable are normally called ''compilation'', and the <tt>gcc</tt> tool allows you to control those stages. The gcc tool does precompilation ''and'' compilation.
+ Q: What is the precompiler?
+ A: Precompilation is the first stage i coverting the raw C source code into a working executable. Precompilation creates a modified version of the source just before the ''proper' compilation begins. In our code the precompilation step read the contents of the header file into the main file.
+ Q: Does the preompiler create an actual file?
+ A: No - compilers normally just use pipes to sending the stuff through the phases of the compiler to make things more efficient.
+ Q: Why do some headers have quotes and other have angle brackets?
+ A: Quotes mean to simply look for a file using a ''relative'' path. So if you just include the name of a file, without including a directory name, the compiler will look in the current directory. If the thing uses angle brackets it will search for the file along a path of directories.
+ Q: What directories will the compiler search when it is looking for header files?
+ A: The <tt>gcc</tt> compiler knows where the standard headers are stored. On a Unix-style operating system, the header files are normally in places like <tt>/usr/local/include</tt>, <tt>/usr/include</tt> and a few others.
+ Q: So that's how it works for standard headers like <tt>stdio.h</tt>?
+ A: Yes. You can read through the <tt>stdio.h</tt> on a Unix-style machine in <tt>/usr/include/stdio.h</tt>. If you have the MingW compiler on Windows, it will probably be in <tt>C:\MingW\include\stdio.h</tt>.
+ Q: Can I create my own libraries?
+ A: Yes - we'll show you how to do that later in the book.
View
308 chapter5/Page 218/code_lots_of_progs.c
@@ -0,0 +1,308 @@
+ typedef struct {
+ char* name;
+ char* opens;
+ char* closes;
+ } island;
+ +---------------+
+ +-----------+ | Skull |
+ | Amity +-------------+ | |
+ +-----------+ V +---------------+
+ +----------+
+ | Craggy |------------------+
+ +----------+ V
+ +-------------+
+ | Isla Nublar +---------------------+
+ +-------------+ |
+ V
+ +-------------+
+ | Shutter |
+ +-------------+
+ +---------------+
+ +-----------+ | Skull |
+ | Amity +-------------+ +---------------------------->| |
+ +-----------+ V | +---------------+
+ +----------+ | |
+ | Craggy |---+ +----------------------+
+ +----------+ V
+ +-------------+
+ | Isla Nublar +---------------------+
+ +-------------+ |
+ V
+ +-------------+
+ | Shutter |
+ +-------------+
+ |-------+--------+-------------+---------|
+ | Amity | Craggy | Isla Nublar | Shutter |
+ |-------+--------+-------------+---------|
+ +-----------------------------------+ +----------------------------------+
+ | | | |
+ | | | |
+ | ISLAND ---------------------->| ANOTHER ISLAND |
+ | | | |
+ | | | |
+ +-----------------------------------+ +----------------------------------+
+ |----------------+--------|
+ | Island airport | |
+ |----------------+--------|
+ | Name | Amity |
+ | Opens | 9AM |
+ | Closes | 5PM |
+ | Next island | Craggy |
+ |----------------+--------|
+ typedef struct island {
+ char* name;
+ char* opens;
+ char* closes;
+ struct island * next;
+ } island;
+ island amity = {"Amity", "09:00", "17:00", NULL};
+ island craggy = {"Craggy", "09:00", "17:00", NULL};
+ island isla_nublar = {"Isla Nublar", "09:00", "17:00", NULL};
+ island shutter = {"Shutter", "09:00", "17:00", NULL};
+ amity.next = &craggy;
+ craggy.next = &isla_nublar;
+ isla_nublar.next = &shutter;
+ island skull = {"Skull", "09:00", "17:00", NULL};
+ isla_nublar.next = &skull;
+ skull.next = &shutter;
+ +-----------------+ +------------------+
+ | | | |
+ | Isla Nublar +-------------------------->| Skull |
+ | | | |
+ +--------+--------+ +-------+----------+
+ X |
+ X |
+ X V
+ X +-------------------+
+ X | |
+ +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX>+ Shutter |
+ | |
+ +-------------------+
+ void display(island* start)
+ {
+ island* i = start;
+ for (; i ____ ______; i ___ _________) {
+ printf("Name: %s open: %s-%s\n", _________, __________, ___________);
+ }
+ }
+ i->closes
+ i->opens
+ i->name
+ i->next
+ NULL
+ !=
+ =
+ void display(island* start)
+ {
+ island* i = start;
+ for (; i '''!=''' '''NULL'''; i '''=''' '''i->next''') {
+ printf("Name: %s open: %s-%s\n", '''i->name''', '''i->opens''', '''i->closes''');
+ }
+ }
+ island amity = {"Amity", "09:00", "17:00", NULL};
+ island craggy = {"Craggy", "09:00", "17:00", NULL};
+ island isla_nublar = {"Isla Nublar", "09:00", "17:00", NULL};
+ island shutter = {"Shutter", "09:00", "17:00", NULL};
+ amity.next = &craggy;
+ craggy.next = &isla_nublar;
+ isla_nublar.next = &shutter;
+ island skull = {"Skull", "09:00", "17:00", NULL};
+ isla_nublar.next = &skull;
+ skull.next = &shutter;
+ display(&amity);
+ > gcc tour.c -o tour && ./tour
+ Name: Amity
+ Open: 09:00-17:00
+ Name: Craggy
+ Open: 09:00-17:00
+ Name: Isla Nublar
+ Open: 09:00-17:00
+ Name: Skull
+ Open: 09:00-17:00
+ Name: Shutter
+ Open: 09:00-17:00
+ >
+ Delfino Isle
+ Angel Island
+ Wild Cat Island
+ Neri's Island
+ Great Todday
+ ...
+ island amity = {"Amity", "09:00", "17:00", NULL};
+ island craggy = {"Craggy", "09:00", "17:00", NULL};
+ island isla_nublar = {"Isla Nublar", "09:00", "17:00", NULL};
+ island shutter = {"Shutter", "09:00", "17:00", NULL};
+ #include <stdlib.h>
+ ...
+ malloc(sizeof(island));
+ island* p = (island*)malloc(sizeof(island));
+ free(p);
+ island* create(char* name)
+ {
+ island* i = (island*)malloc(sizeof(island));
+ i->name = name;
+ i->opens = "09:00";
+ i->closes = "17:00";
+ i->next = NULL;
+ return i;
+ }
+ island* create(char* name)
+ {
+ island* i = (island*)malloc(sizeof(island));
+ i->name = name;
+ i->opens = "09:00";
+ i->closes = "17:00";
+ i->next = NULL;
+ return i;
+ }
+ char name[80];
+ fgets(name, 79, stdin);
+ island* p_island0 = create(name);
+ $ ./test_flight
+ Atlantis
+ fgets(name, 79, stdin);
+ island* p_island1 = create(name);
+ p_island0->next = p_island1;
+ Titchmarsh Island
+ display(p_island0);
+ Name: Titchmarsh Island
+ open: 09:00-17:00
+ Name: Titchmarsh Island
+ open: 09:00-17:00
+ ________________________________________
+ island* create(char* name)
+ {
+ island* i = (island*)malloc(sizeof(island));
+ i->name = name;
+ i->opens = "09:00";
+ i->closes = "17:00";
+ i->next = NULL;
+ return i;
+ }
+ char name[80];
+ fgets(name, 79, stdin);
+ island* p_island0 = create(name);
+ fgets(name, 79, stdin);
+ island* p_island1 = create(name);
+ Both islands share the same name string
+ +-------------------+ +----------------------+
+ | | | |
+ | island0 | | island1 |
+ | | | |
+ | | | |
+ +-----------+-------+ --+----------------------+
+ | -----/
+ | -----/
+ | -----/
+ | -----/
+ | -----/
+ | -----/
+ +-/
+ V
+ |---+---+---+---+---+---+---+---+---+---+---+---+---+-----|
+ | | | | | | | | | | | | | | ... |
+ |---+---+---+---+---+---+---+---+---+---+---+---+---+-----|
+ char* s = "MONA LISA";
+ |---+---+---+---+---+---+---+---+---+----|
+ | M | O | N | A | | L | I | S | A | \0 |
+ |---+---+---+---+---+---+---+---+---+----|
+ char* copy = strdup(s);
+ island* create(char* name)
+ {
+ island* i = (island*)malloc(sizeof(island));
+ i->name = '''strdup(name)''';
+ i->opens = "09:00";
+ i->closes = "17:00";
+ i->next = NULL;
+ return i;
+ }
+ ./test_flight
+ Atlantis
+ Titchmarsh Island
+ Name: Atlantis
+ open: 09:00-17:00
+ Name: Titchmarsh Island
+ open: 09:00-17:00
+ island* start = NULL;
+ island* i = NULL;
+ island* next = NULL;
+ char name[80];
+ for(; ______________________ != ________________; i = ________) {
+ next = create(name);
+ if (start == NULL)
+ start = ______;
+ if (i != NULL)
+ i ___ ______ = next;
+ }
+ display(start);
+ fgets(name, 79, stdin)
+ NULL
+ next
+ next
+ next
+ ->
+ .
+ NULL
+ island* start = NULL;
+ island* i = NULL;
+ island* next = NULL;
+ char name[80];
+ for(; fgets(name, 79, stdin) != NULL; i = next) {
+ next = create(name);
+ if (start == NULL)
+ start = next;
+ if (i != NULL)
+ i->next = next;
+ }
+ display(start);
+ .
+ NULL
+ void release(island* start)
+ {
+ island* i = start;
+ island* next = NULL;
+ for (; i != NULL; i = next) {
+ next = ________________;
+ _____________________;
+ _____________________;
+ }
+ }
+ void release(island* start)
+ {
+ island* i = start;
+ island* next = NULL;
+ for (; i != NULL; i = next) {
+ next = i->next;
+ free(i->name);
+ free(i);
+ }
+ }
+ display(start);
+ release(start);
+ ./tour < trip1.txt
+ Name: Delfino Isle
+ Open: 09:00-17:00
+ Name: Angel Island
+ Open: 09:00-17:00
+ Name: Wild Cat Island
+ Open: 09:00-17:00
+ Name: Neri's Island
+ Open: 09:00-17:00
+ Name: Great Todday
+ Open: 09:00-17:00
+ Name: Ramita de la Baya
+ Open: 09:00-17:00
+ Name: Island of the Blue Dolphins
+ Open: 09:00-17:00
+ Name: Fantasy Island
+ Open: 09:00-17:00
+ Name: Farne
+ Open: 09:00-17:00
+ Name: Isla de Muerta
+ Open: 09:00-17:00
+ Name: Tabor Island
+ Open: 09:00-17:00
+ Name: Haunted Isle
+ Open: 09:00-17:00
+ Name: Sheena Island
+ Open: 09:00-17:00
View
242 chapter5/Page 30/code_lots_of_progs.c
@@ -0,0 +1,242 @@
+ Sale today:
+ 6 apples
+ 1.5 lb strawberries
+ 0.5 pint orange juice
+ typedef struct {
+ ...
+ short count;
+ float weight;
+ float volume;
+ ...
+ } fruit;
+ * It will take up more space in memory.
+ * Someone might set more than one value.
+ * There's nothing called "quantity".
+ |------------+---------+-------------|
+ | char* name | int age | float wight |
+ |------------+---------+-------------|
+ Dog d = {"Buff", 2, 98.5};
+ |---------------------------------------|
+ | quantity (might be a float or a short) |
+ |---------------------------------------|
+ typedef union {
+ short count;
+ float weight;
+ float volume;
+ } quantity;
+ quantity q = {4};
+ quantity q = {.weight=1.5};
+ quantity q;
+ q.float = 3.7;
+ typedef struct {
+ const char * color;
+ int gears;
+ int height;
+ } bike;
+ bike b = {.height=17, .gears=21};
+ typedef struct {
+ const char* name;
+ const char* country;
+ quantity amount;
+ } fruit_order;
+ fruit_order apples = {"apples", "England", .amount.weight=4.2};
+ printf("This order contains %2.2f lbs of %s\n", apples.amount.weight, apples.name);
+ typedef union {
+ float lemon;
+ int lime_pieces;
+ } lemon_lime;
+
+ typedef struct {
+ float tequila;
+ float cointreau;
+ lemon_lime citrus;
+ } margarita;
+ margarita m = {2.0, 1.0, {0.5}};
+ margarita m = {2.0, 1.0, .citrus.lemon=2};
+ margarita m = {2.0, 1.0, 0.5};
+ margarita m = {2.0, 1.0, {.lime_pieces=1}};
+ margarita m = {2.0, 1.0, {1}};
+ margarita m = {2.0, 1.0, {2}};
+ Name: The Juicy, Juicy
+ ______________________________________________________
+ printf("%2.1f measures of tequila\n%2.1f measures of cointreau\n%2.1f measures of juice\n",
+ m.tequila, m.cointreau, m.citrus.lemon);
+
+ 2.0 measures of tequila
+ 1.0 measures of cointreau
+ 2.0 measures of juice
+ Name: The I Can't Feel My Legs
+ ______________________________________________________
+ printf("%2.1f measures of tequila\n%2.1f measures of cointreau\n%2.1f measures of juice\n",
+ m.tequila, m.cointreau, m.citrus.lemon);
+
+ 2.0 measures of tequila
+ 1.0 measures of cointreau
+ 0.5 measures of juice
+ Name: The Don't Suck On This
+ ______________________________________________________
+ printf("%2.1f measures of tequila\n%2.1f measures of cointreau\n%i pieces of lime\n",
+ m.tequila, m.cointreau, m.citrus.lime_pieces);
+
+ 2.0 measures of tequila
+ 1.0 measures of cointreau
+ 1 pieces of lime
+ margarita m = {2.0, 1.0, {0.5}};
+ margarita m;
+ m = {2.0, 1.0, {0.5}};
+ __________________________________________________________________________________________________________________
+ __________________________________________________________________________________________________________________
+ __________________________________________________________________________________________________________________
+ typedef union {
+ float lemon;
+ int lime_pieces;
+ } lemon_lime;
+
+ typedef struct {
+ float tequila;
+ float cointreau;
+ lemon_lime citrus;
+ } margarita;
+ margarita m = {2.0, 1.0, .citrus.lemon=2};
+ margarita m = {2.0, 1.0, 0.5};
+ margarita m = {2.0, 1.0, {1}};
+ Name: The Juicy, Juicy
+ '''margarita m = {2.0, 1.0, {2}};'''
+ printf("%2.1f measures of tequila\n%2.1f measures of cointreau\n%2.1f measures of juice\n",
+ m.tequila, m.cointreau, m.citrus.lemon);
+
+ 2.0 measures of tequila
+ 1.0 measures of cointreau
+ 2.0 measures of juice
+ Name: The I Can't Feel My Legs
+ '''margarita m = {2.0, 1.0, {0.5}};'''
+ printf("%2.1f measures of tequila\n%2.1f measures of cointreau\n%2.1f measures of juice\n",
+ m.tequila, m.cointreau, m.citrus.lemon);
+
+ 2.0 measures of tequila
+ 1.0 measures of cointreau
+ 0.5 measures of juice
+ Name: The Don't Suck On This
+ '''margarita m = {2.0, 1.0, {.lime_pieces=1}};'''
+ printf("%2.1f measures of tequila\n%2.1f measures of cointreau\n%i pieces of lime\n",
+ m.tequila, m.cointreau, m.citrus.lime_pieces);
+
+ 2.0 measures of tequila
+ 1.0 measures of cointreau
+ 1 pieces of lime
+ margarita m = {2.0, 1.0, {0.5}};
+ margarita m;
+ m = {2.0, 1.0, {0.5}};
+ It doesn't compile because the compiler will only know that {2.0, 1.0, {0.5}} represents a struct if it's use
+ on the same line that a struct is declared. When it's on a separate line the compiler thinks it's an '''array'''.
+ typedef union {
+ float weight;
+ int count;
+ } muffin;
+
+ int main()
+ {
+ muffin order = {2};
+ printf("Muffins quantity: %i\n",
+ order.count);
+ return 0;
+ }
+ $ gcc badunion.c -o badunion && ./badunion
+ Muffins quantity: 1073741824
+ $
+ enum colors {RED, GREEN, PUCE};
+ enum colors favorite = PUCE;
+ enum colors favorite = PUSE;
+ #include <stdio.h>
+
+ typedef enum {
+ COUNT, POUNDS, PINTS
+ } unit_of_measure;
+
+ typedef union {
+ short count;
+ float weight;
+ float volume;
+ } quantity;
+
+ typedef struct {
+ const char* name;
+ const char* country;
+ quantity amount;
+ unit_of_measure units;
+ } fruit_order;
+
+ void display(fruit_order order)
+ {
+ printf("This order contains ");
+ if (_____________ == PINTS)
+ printf("%2.2f pints of %s\n", order.amount.________, order.name);
+ else if (_____________ == _______)
+ printf("%2.2f lbs of %s\n", order.amount.weight, order.name);
+ else
+ printf("%i %s\n", order.amount._______, order.name);
+ }
+
+ int main()
+ {
+ fruit_order apples = {"apples", "England", .amount.count=144, _______};
+ fruit_order strawberries = {"strawberries", "Spain", .amount.________=17.6, POUNDS};
+ fruit_order oj = {"orange juice", "U.S.A.", .amount.volume=10.5, _______};
+ display(apples);
+ display(strawberries);
+ display(oj);
+ return 0;
+ }
+ PINTS
+ weight
+ COUNT
+ order.units
+ order.units
+ volume
+ POUNDS
+ count
+ #include <stdio.h>
+
+ typedef enum {
+ COUNT, POUNDS, PINTS
+ } unit_of_measure;
+
+ typedef union {
+ short count;
+ float weight;
+ float volume;
+ } quantity;
+
+ typedef struct {
+ const char* name;
+ const char* country;
+ quantity amount;
+ unit_of_measure units;
+ } fruit_order;
+
+ void display(fruit_order order)
+ {
+ printf("This order contains ");
+ if ('''order.units''' == PINTS)
+ printf("%2.2f pints of %s\n", order.amount.'''volume''', order.name);
+ else if ('''order.units''' == '''POUNDS''')
+ printf("%2.2f lbs of %s\n", order.amount.weight, order.name);
+ else
+ printf("%i %s\n", order.amount.'''count''', order.name);
+ }
+
+ int main()
+ {
+ fruit_order apples = {"apples", "England", .amount.'''count'''=144, COUNT};
+ fruit_order strawberries = {"strawberries", "Spain", .amount.'''weight'''=17.6, POUNDS};
+ fruit_order oj = {"orange juice", "U.S.A.", .amount.'''volume'''=10.5, PINTS};
+ display(apples);
+ display(strawberries);
+ display(oj);
+ return 0;
+ }
+ $ gcc enumtest.c -o enumtest
+ This order contains 144 apples
+ This order contains 17.60 lbs of strawberries
+ This order contains 10.50 pints of orange juice
+ $
View
15 chapter5/Page 38/code_includes_shell.c
@@ -0,0 +1,15 @@
+ typedef union {
+ float weight;
+ int count;
+ } cupcake;
+
+ int main()
+ {
+ cupcake order = {2};
+ printf("Cupcakes quantity: %i\n",
+ order.count);
+ return 0;
+ }
+ $ gcc badunion.c -o badunion && ./badunion
+ Cupcakes quantity: 1073741824
+ $
View
598 chapter6/Page 278/code_lots_of_progs.c
@@ -0,0 +1,598 @@
+ Q: If the <tt>island</tt> struct had a name '''array''' rather than a character pointer, would we need to use strdup() here?
+ A: No. Each island <tt>struct</tt> would store it's own copy, so you wouldn't need to make your own copy.
+ Q: So why would I want to use char pointers rather than char arrays in my data structures?
+ A: Char pointers won't limit the amount of space you need to set aside for strings. If you use char arrays, you will need to decide in advance exactly how long your strings might need to be.
+ const int NUM_ADS = 7;
+ char* ADS[] = {
+ "William: SBM GSOH likes sports, TV, dining",
+ "Matt: SWM NS likes art, movies, theater",
+ "Luis: SLM ND likes books, theater, art",
+ "Mike: DWM DS likes trucks, sports and bieber",
+ "Peter: SAM likes chess, working out and art",
+ "Josh: SJM likes sports, movies and theater",
+ "Jed: DBM likes theater, books and dining"
+ };
+
+ void find()
+ {
+ int i;
+ puts("Search results:");
+ puts("------------------------------------");
+ for (i = 0; i ___ _________; i++) {
+ if (________(________, __________)
+ ____ ___ ________(________, __________)) {
+ printf("%s\n", ADS[i]);
+ }
+ }
+ puts("------------------------------------");
+ }
+ <
+ NUM_ADS
+ strstr
+ strstr
+ !
+ &&
+ ADS[i]
+ ADS[i]
+ "sports"
+ "bieber"
+ ||
+ strcmp
+ strcmp
+ void find()
+ {
+ int i;
+ print("Search results:\n");
+ print("------------------------------------\n");
+ for (i = 0; i < NUM_ADS; i++) {
+ if (strstr(ADS[i], "sports")
+ && !strstr(ADS[i], "bieber")) {
+ printf("%s\n", ADS[i]);
+ }
+ }
+ print("------------------------------------\n");
+ }
+ ||
+ strcmp
+ strcmp
+ > gcc find.c -o find && ./find
+ Search results:
+ ------------------------------------
+ William: SBM GSOH likes sports, TV, dining
+ Josh: SJM likes sports, movies and theater
+ ------------------------------------
+ >
+ int sports_no_bieber(char* s)
+ {
+ return strstr(s, "sports") && !strstr(s, "bieber");
+ }
+ void find( function-name match )
+ {
+ int i;
+ puts("Search results:");
+ puts("------------------------------------");
+ for (i = 0; i < NUM_ADS; i++) {
+ if ( call-the-match-function (ADS[i])) {
+ printf("%s\n", ADS[i]);
+ }
+ }
+ puts("------------------------------------");
+ }
+ find(sports_no_bieber);
+ find(sports_or_workout);
+ find(ns_theater);
+ find(arts_theater_or_dining);
+ int go_to_warp_speed(int speed)
+ {
+ dilithium_crystals(ENGAGE);
+ warp = speed;
+ reactor_core(c, 125000 * speed, PI);
+ clutch(DISENGAGE);
+ return 0;
+ }
+ go_to_warp_speed(4);
+ int* a;
+ function* f;
+ int go_to_warp_speed(int speed)
+ {
+ ...
+ }
+ char** album_names(char* artist, int year)
+ {
+ ...
+ }
+ int (*warp_fn)(int);
+ warp_pointer = go_to_warp_speed;
+ warp_fn(4);
+ char** (*names_fn)(char*,int);
+ names_fn = album_names;
+ char** results = names_fn("Sacha Distel", 1972);
+ |-------------+----+------------------+----+-------------+---|
+ | RETURN TYPE | (* | POINTER VARIABLE | )( | PARAM TYPES | ) |
+ | char** | (* | names_fn | )( | char*,int | |
+ |-------------+----+------------------+----+-------------+---|
+ int sports_no_bieber(char* s)
+ {
+ return strstr(s, "sports") && !strstr(s, "bieber");
+ }
+ int sports_or_workout(char* s)
+ {
+ ________________________________________________________
+ }
+ int ns_theater(char* s)
+ {
+ _________________________________________________________
+ }
+ int arts_theater_or_dining(char* s)
+ {
+ ________________________________________________________________________
+ }
+ void find(____________________________)
+ {
+ int i;
+ puts("Search results:");
+ puts("------------------------------------");
+ for (i = 0; i < NUM_ADS; i++) {
+ if (match(ADS[i])) {
+ printf("%s\n", ADS[i]);
+ }
+ }
+ puts("------------------------------------");
+ }
+ int sports_no_bieber(char* s)
+ {
+ return strstr(s, "sports") && !strstr(s, "bieber");
+ }
+ int sports_or_workout(char* s)
+ {
+ return strstr(s, "sports") || strstr(s, "working out");
+ }
+ int ns_theater(char* s)
+ {
+ return strstr(s, "NS") && strstr(s, "theater");
+ }
+ int arts_theater_or_dining(char* s)
+ {
+ return strstr(s, "arts") || strstr(s, "theater") || strstr(s, "dining");
+ }
+ void find(int (*match)(char*))
+ {
+ int i;
+ puts("Search results:");
+ puts("------------------------------------");
+ for (i = 0; i < NUM_ADS; i++) {
+ if (match(ADS[i])) {
+ printf("%s\n", ADS[i]);
+ }
+ }
+ puts("------------------------------------");
+ }
+ int main()
+ {
+ find(sports_no_bieber);
+ find(sports_or_workout);
+ find(ns_theater);
+ find(arts_theater_or_dining);
+ return 0;
+ }
+ > ./find
+ Search results:
+ ------------------------------------
+ William: SBM GSOH likes sports, TV, dining
+ Josh: SJM likes sports, movies and theater
+ ------------------------------------
+ Search results:
+ ------------------------------------
+ William: SBM GSOH likes sports, TV, dining
+ Mike: DWM DS likes trucks, sports and bieber
+ Peter: SAM likes chess, working out and art
+ Josh: SJM likes sports, movies and theater
+ ------------------------------------
+ Search results:
+ ------------------------------------
+ Matt: SWM NS likes art, movies, theater
+ ------------------------------------
+ Search results:
+ ------------------------------------
+ William: SBM GSOH likes sports, TV, dining
+ Matt: SWM NS likes art, movies, theater
+ Luis: SLM ND likes books, theater, art
+ Josh: SJM likes sports, movies and theater
+ Jed: DBM likes theater, books and dining
+ ------------------------------------
+ >
+ Q: If function pointers are just pointers, why don't you need to prefix them with a '*' when you call the function?
+ A: You can. In the program, instead of writing "match(ADS[i])", you could have written "(*match)(ADS[i])".
+ Q: And could we have used "&" to get the address of a method?
+ A: Yes. Instead of "find(sports_or_workout)" you could have written "find(&sports_or_workout)".
+ Q: Then why didn't we?
+ A: Because it's very elegant to read code that way. If you skip the "*" and "&" then C will still understand what you're saying.
+ Q: But for every ''other'' type of pointer we'll have to use the "*" and "&" operators?
+ A: Yes. Function pointers are the only ones that don't need * and &.
+ qsort(void *array, size_t length, size_t item_size, int (*compar)(const void *, const void *));
+ int scores[] = {543,323,32,554,11,3,112};
+ int compare_scores(void* score_a, void* score_b)
+ {
+ ...
+ }
+ int a = *(int*)score_a;
+ int b = *(int*)score_b;
+ return a - b;
+ qsort(scores, 7, sizeof(int), compare_scores);
+ int compare_scores(void* score_a, void* score_b)
+ {
+ int a = *(int*)score_a;
+ int b = *(int*)score_b;
+ return a - b;
+ }
+ int compare_scores_desc(void* score_a, void* score_b)
+ {
+ ______________________________________
+ ______________________________________
+ ______________________________________
+ ______________________________________
+ }
+ typedef struct {
+ int width;
+ int height;
+ } rectangle;
+ int compare_areas(void* a, void* b)
+ {
+ _________________________________________
+ _________________________________________
+ _________________________________________
+ _________________________________________
+ _________________________________________
+ _________________________________________
+ }
+ int compare_names(void* a, void* b)
+ {
+ ___________________________
+ ___________________________
+ ___________________________
+ ___________________________
+ }
+ int compare_areas_desc(void* a, void* b)
+ {
+ _____________________________
+ _____________________________
+ }
+ int compare_names_desc(void* a, void* b)
+ {
+ _____________________________
+ _____________________________
+ }
+ int compare_scores(void* score_a, void* score_b)
+ {
+ int a = *(int*)score_a;
+ int b = *(int*)score_b;
+ return a - b;
+ }
+ int compare_scores_desc(void* score_a, void* score_b)
+ {
+ int a = *(int*)score_a;
+ int b = *(int*)score_b;
+ return b - a;
+ }
+ typedef struct {
+ int width;
+ int height;
+ } rectangle;
+ int compare_areas(void* a, void* b)
+ {
+ rectangle* ra = (rectangle*)a;
+ rectangle* rb = (rectangle*)b;
+ int area_a = (ra->width * ra->height);
+ int area_b = (rb->width * rb->height);
+ return area_a - area_b;
+ }
+ int compare_names(void* a, void* b)
+ {
+ char** sa = (char**)a;
+ char** sb = (char**)b;
+ return strcmp(*sa, *sb);
+ }
+ int compare_areas_desc(void* a, void* b)
+ {