Notes
Slide Show
Outline
1
CS 211:
Introduction to Computer Programming II
  • Instructor: Brian M. Dennis
  • Teaching Assistants:
  • Tom Lechner, Bin Lin, Rachel Goldsborough
  • http://www.cs.northwestern.edu/~bmd/cs211/


2
Data Abstraction
  • SICP Chapter 2 intro


  • Thus, whereas our focus in chapter 1 was on building abstractions by combining procedures to form compound procedures, we turn in this chapter to another key aspect of any programming language: the means it provides for building abstractions by combining data objects to form compound data.


  • Why do we want compound data in a programming language? For the same reasons that we want compound procedures: to elevate the conceptual level at which we can design our programs, to increase the modularity of our designs, and to enhance the expressive power of our language. Just as the ability to define procedures enables us to deal with processes at a higher conceptual level than that of the primitive operations of the language, the ability to construct compound data objects enables us to deal with data at a higher conceptual level than that of the primitive data objects of the language.
3
Structs
  • C/C++
    • User defined datatype
    • Collections
    • Typed fields
    • Heterogeneous
    • Accessed by named slots
    • Unordered
      • Conceptually
  • Scheme
    • Really no analog
    • No user defined datatypes
    • Vectors indexed by integer
    • Can fake it with lists/vectors + procedures
      • Takes discipline
4
Basics of Structs
  • // An example of declaring
  • // a new user defined type
  • enum Hit { SINGLE = 0, DOUBLE, TRIPLE, HOMER };
  • struct MLBPlayer {
  • char* name;
  • char* team;
  • int at_bats;
  • int walks;
  • int hits[4];
  • float batting_average;
  • bool hits_lefty;
  • };
5
Basics of Structs
  • // An example of declaring instances of our
  • // new user defined type
  • int main(int argc, char* argv[]) {
  • MLBPlayer arod = {
  • "Alex Rodriguez", "Texas Rangers",
  • 0, 0, {0, 0, 0, 0}, 0.0f, false
  • };
  • return 0;
  • }
6
Basics of Structs
  • // An example of declaring instances of our
  • // new user defined type, and accessing fields
  • int main(int argc, char* argv[]) {
  • // Stuff elided…


  • MLBPlayer bbonds;
  • bbonds.name = "Barry Bonds";
  • bbonds.team = "SF Giants";
  • bbonds.hits_lefty = true;


  • return 0;
  • }
7
Basics of Structs
  • // A constructor function for our datatype
  • MLBPlayer make_player(char* name, char* team) {
  • MLBPlayer temp_player;
  • int cnt = strlen(name) + 1;
  • temp_player.name = new char[cnt];
  • // temp_player.name = (char*)malloc(cnt);
  • strcpy(temp_player.name, name);


  • cnt = strlen(team) + 1;
  • temp_player.team = new char[cnt];
  • strcpy(temp_player.team, team);
  • // Initialize the rest of the player


  • return temp_player;
  • |


8
Basics of Structs
  • // You can have arrays of players
  • // You can have pointers to players
  • int main(int argc, char* argv[]) {
  • // Stuff elided…
  • MLBPlayer frank_thomas;
  • // An array of players
  • MLBPlayer cubs[25];
  • cubs[20].name = "Henry Rodriguez";


  • // A pointer to a player;
  • MLBPlayer* bmd_wishes = &frank_thomas;
  • for (int i = 0; i < 4; i++) {
  • bmd_wishes->hits[i] = 0;
  • }
  • }
9
Function Pointers

  • int slugger(MLBPlayer* hitter,
  •     MLBPlayer* pitcher) {
  • if (!(rand() % 4)) {
  • return HOMER;
  • } else {
  • return -1;
  • }
  • }
10
Function Pointers

  • int leadoff(MLBPlayer* hitter,
  •     MLBPlayer* pitcher) {
  • int val = rand() % 24;
  • switch (val) {
  • case 0:
  • case 1:
  • case 2:
  • return SINGLE;
  • case 3:
  • case 4:
  • return DOUBLE;
  • case 5:
  • return TRIPLE;
  • case 6:
  • return HOMER;
  • default:
  • return -1;
  • }
  • }
11
Function Pointers
  • // An example of declaring
  • // a new user defined type
  • enum Hit { SINGLE = 0, DOUBLE, TRIPLE, HOMER };
  • struct MLBPlayer {
  • char* name;
  • char* team;
  • int at_bats;
  • int walks;
  • int hits[4]
  • float batting_average;
  • bool hits_lefty;
  • int (*hit_func)(MLBPlayer*, MLBPlayer*);
  • };
12
Function Pointers
  • MLBPlayer pedro =
  • make_player("Pedro Martinez", "Boston Red Sox");


  • bbonds.hit_func = slugger;
  • bmd_wishes->hit_func = leadoff;


  • int at_bat(MPlayer* hitter, MPlayer* pitcher) {
  • hitter->hit_func(hitter, pitcher);
  • }


13
Basics of Structs
  • // Another user defined type
  • const int MAX_NEIGHBORS = 1024;


  • struct GraphNode {
  • int unique_id;
  • GraphNode neighbors[MAX_NEIGHBORS];
  • };
14
Basics of Structs
  • // Another user defined type
  • // Fixed up to deal with recursive type
  • const int MAX_NEIGHBORS = 1024;


  • struct GraphNode {
  • int unique_id;
  • GraphNode* neighbors[MAX_NEIGHBORS];
  • };
15
Basics of Structs
  • #ifndef _INT_LIST_H_
  • #define _INT_LIST_H_
  • // An oldie by goodie


  • struct IntListCell;
  • typedef IntListCell* IntList;


  • struct IntListCell {
  • int value;
  • IntList tail;
  • };
  • #endif
16
Basics of Structs
  • #include <iostream>
  • #include <cstring>
  • #include "IntList.h"
  • using namespace std;


  • int main(int argc, char* argv[]) {
  • // Build up a list of integers
  • IntList head = 0;
  • for (int j = 1; j < argc; j++) {
  • IntList new_head = new IntListCell;
  • new_head->value = strlen(argv[j])
  • new_head->tail = head;
  • head = new_head;
  • }
  • return 0;
  • }
17
Issues with structs
  • Initialization
    • Not guaranteed
    • Done by hand
  • Packaging datatypes & behavior
    • Connecting
  • Reuse / extension
    • Salaried players
18
That’s a Wrap
  • Takeaway
    • Structs
      • User define datatypes
      • Collection of typed, named slots
      • Instances first class
    • Function pointers
      • First class
    • Structs are lame
  • Reading
    • 6.1 – 6.4 (structs)
    • 4.9 (function pointers)
    • 5.11 (multidimensional arrays)
    • Appendix C
      • If you need it