Presentation is loading. Please wait.

Presentation is loading. Please wait.

Structs (C) Already seen in tirgul.

Similar presentations


Presentation on theme: "Structs (C) Already seen in tirgul."— Presentation transcript:

1 Structs (C) Already seen in tirgul

2 Structs Contiguously-allocated region of memory
Refer to members within structure by names Members may be of different types Example: Memory Layout struct rec {    int i;    int a[3];    int *p; }; i a p 4 16 Pointers are 4 bytes

3 Struct initialization
structs can be initialized in a way similar to arrays: struct rec {    int i;    int a[3];    int *p; }; int k; struct rec r = { 5, { 0,1,2}, &k }; r.i=1; r.a[0]=5; r.p=&k;

4 typedef Synonyms for variable types – make your program more readable
typdef unsigned int size_t; Already seen in tirgul

5 typedef in C No need to write “struct Complex” each time:
typedef struct Complex {    double _real, _imag; } Complex; Complex addComplex(Complex, Complex); Complex subComplex(Complex, Complex); complex.h Already seen in tirgul

6 C++ No need to write “struct Complex” each time even if we don’t use a typedef struct Complex {    double _real, _imag; } Complex; Complex addComplex(Complex, Complex); Complex subComplex(Complex, Complex); complex.h Already seen in tirgul

7 Pointers to structs You can have a pointer to structures or array or structs the same way you have pointers to built in type. Pointers to anything can be cast between themselves, it may be useful sometimes, but beware…

8 Structs - Code Offset of each structure member determined at compile time r struct rec {    int i;    int a[3];    int *p; }; i a p 4 16 r *idx int *find_a(struct rec *r, int idx) {    return &(r->a[idx]); }

9 struct Sequential in memory, but may have gaps: sizeof(S1) != sizeof(char)+sizeof(double)+sizeof(int)*2 Member offset determined in compile time Access member with "." e.g. a.i[0], a.v. Access member of struct pointer contents: (*p). or p-> struct S1 {    char c;    int i[2];    double v; } struct S1 a,*p; How would this look under linux gcc? v i[0] c i[1] P+0 P+4 P+16 P+24

10 Structs – poor oop complex.h complex.c MyProg.c
struct Complex {    double _real, _imag; }; struct Complex addComplex(struct Complex, struct Complex); complex.h Complex.c #include "complex.h" // implementation struct Complex addComplex(struct Complex a, struct Complex b) { complex.c #include "complex.h" int main() {    struct Complex c; ... MyProg.c

11 #ifndef – header safety
Complex.h: struct Complex { ...      MyStuff.h: #include "Complex.h" Main.c: #include "MyStuff.h" #include "Complex.h" Only one definition is allowed! Error: Complex.h:1: redefinition of `struct Complex'

12 #ifndef – header safety
Complex.h (revised): #ifndef COMPLEX_H #define COMPLEX_H struct Complex { ... #endif Main.c: #include "MyStuff.h" #include "Complex.h" // no error this time

13 #pragma once – header safety
Complex.h (revised): #pragma once struct Complex { ... Main.c: #include "MyStuff.h" #include "Complex.h" // no error this time

14 Copy structs using ‘=‘: copy just struct values!!!
structs copying Copy structs using ‘=‘: copy just struct values!!! Complex a,b; a._real = 5; a._imag = 3; b = a; _real = 5 _imag = 3 a: _real = ? _imag = ? b:

15 Copy structs using ‘=‘: copy just struct values!!!
structs copying Copy structs using ‘=‘: copy just struct values!!! Complex a,b; a._real = 5; a._imag = 3; b = a; _real = 5 _imag = 3 a: b:

16 Arrays in structs copying
struct definition: typedef struct Vec {    double _arr [MAX_SIZE]; } Vec; Vec addVec(Vec, Vec); ... vec.h

17 Arrays in structs copying
copy struct using ‘=‘: Vec a,b; a._arr[0] = 5; a._arr[1] = 3; b = a; _arr = {5,3,?,…} a: _arr = {?,?,?,…} b:

18 Arrays in structs copying
Copy struct using ‘=‘: copy just struct values!!! Vec a,b; a._arr[0] = 5; a._arr[1] = 3; b = a; _arr = {5,3,?,…} a: b:

19 But !!!

20 Pointers in structs copying
struct definition: typedef struct Vec {    double _arr [MAX_SIZE];    double * _p_arr; } Vec; Vec addVec(Vec, Vec); ... vec.h

21 Pointers in structs copying
Copy structs using ‘=‘: copy just struct values!!! Vec a,b; a._arr[0] = 5; a._arr[1] = 3; a._p_arr = a._arr; b = a; _arr = {5,3,?,…} _p_arr = 0x55 a: _arr = {?,?,?,…} _p_arr = ? b:

22 Pointers in structs copying
Copy structs using ‘=‘: copy just struct values!!! Vec a,b; a._arr[0] = 5; a._arr[1] = 3; a._p_arr = a._arr; b = a; _arr = {5,3,?,…} _p_arr = 0x55 a: _arr = {?,?,?,…} b: Pointers copied by value!!!

23 Pointers in structs copying
The result: Vec a,b; a._arr[0] = 5; a._arr[1] = 3; a._p_arr = a._arr; b = a; *(b._p_arr) = 8; printf ("%f", a._arr[0]); // output 8

24 How to copy structs correctly?
Implement a clone function: void cloneVec (Vec *a, Vec *b) {    int i=0;    for (i=0;I<MAX_SIZE;i++)    {       b->_arr[i] = a->_arr[i];    }    b->_p_arr = b->_arr; }

25 Arrays & structs as arguments
When an array is passed as an argument to a function, the address of the 1st element is passed. Structs are passed by value, exactly as the basic types. Array == (in run time) pointer to the first element!

26 Arrays & structs as arguments
struct MyStr {    int _a[10]; }; void f(int a[]) {    a[7] = 89; } void g(MyStr s) {    s._a[7] = 84; } main() {    MyStr x;    x._a[7] = 0;    f(x._a);    printf("%d\n", x._a[7]);    g(x);    printf("%d\n", x._a[7]); } Output: 89

27 Access to struct members via pointers
struct MyStr {    int _a[10]; }; main() {    MyStr x;    MyStr *p_x = &x;    x._a[2] = 3;    (*p_x)._a[3] = 5;    p_x->_a[4] = 6; } Just a reminder.

28 Classes (C++)

29 Motivating Example Goal: Graphics package Handle drawing of different shapes Maintain list of shapes

30 Solution #1 struct shape {    enum    {       RECTANGLE, CIRCLE, TRIANGLE    } _type;    double _x, _y;    double _height, _width; }; void Draw( shape const* Shape ) {    switch( Shape->type )    {       case RECTANGLE:       ...       case CIRCLE: ... 

31 Solution #1 - Discussion
Pros: Simple, direct Cons: Adding new shapes requires changing all procedures that deal with shape A lot of "if"/"switch" in runtime

32 Solution #3 – C++ classes
Language provides tools for objects Ideas similar to Java, but many differences in details. (We will not show this solution now, since we need yet to learn these details…)

33 Simple Class Declaration
#ifndef _COUNTER_H_ #define _COUNTER_H_ class Counter { public:    Counter(); // Constructor void increment(); // A method int value(); // Another one private:    int _count; }; #endif // _COUNTER_H_ Note: private members are part of the interface file (because they appear at the h file, not on purpose)

34 Using the class #include "Counter.h" #include <cstdio> int main() {    Counter cnt; // Call to constructor! printf("Initial value= %d\n", cnt.value());    cnt.increment();    printf("New value = %d\n", cnt.value() ); } Where is the class stored? Like a c struct, on the stack!

35 Class Implementation void Counter::increment() { _count++; }
int Counter::value() {    return _count; } Scope operator

36 Class Implementation Constructor - like a function, but no return type
Counter::Counter() {    _count = 0; }

37 How do we compile it? g++ -c -Wall Counter.cpp –o Counter.o
g++ -c -Wall app.cpp –o app.o g++ -Wall Counter.o app.o –o app g++ / gcc? g++ is the c++ compiler. But gcc is the "compiler collection" and will select the language according to file extension so you may well use gcc.

38 Declaration + implementation
#ifndef _COUNTER_H_ #define _COUNTER_H_ class Counter { public:    Counter(); // Constructor // A method with inline implementation : void increment(){ _count++; } private:    int _count; }; #endif // _COUNTER_H_

39 Class Basics: Public/Private
Declare which parts of the class are accessible outside the class class Foo { public:     // accessible from outside private: // private - not accessible from outside // (compilation error) // but visible to user! };

40 Class Basics: Public/Private
Declare which parts of the class are accessible outside the class class Foo { public:     // accessible from outside private: // private - not accessible from outside // (compilation error) // but visible to user! }; Without using “dirty” tricks

41 Example class MyClass { public:    int a();    double _x; private:    int b();    double _y; }; int main() {    MyClass foo;    // legal: foo._x = 1.0;    foo.a();    //compile error: foo._y = 2.0;    foo.b(); }

42 Example class MyClass { public:    int a();    double _x; private:    int b();    double _y; }; int MyClass::a() {    // legal _x = 1.0;    // also legal _y = 2.0;    b(); }

43 Example - Point class Point { public: Point(int x, int y); ~Point();
int getX() const; int getY() const; private: int _x, _y; };

44 Circle #include "Point.h" class Circle { public:
Circle(int x, int y, double r); ~Circle(); // ... private: Point _center; // ... };

45 Circle.cpp #include "Circle.h“
Circle::Circle(int x, int y, double r) : _center(x,y) {    // ... } Circle::~Circle() {    printf("in ~Circle()"); }

46 this The address of the instance for which the member method was invoked class Node {    Node* next; public:    bool isChild(const Node*) const;    // ... }; bool Node::isChild(const Node* other) const {    for (const Node* curr=this; curr; curr=curr->next)    {       if (curr==other) return true;    }    return false; }

47 structs Where did structs go?
In C++ class==struct, except that by default struct members are public and class members are private: int main() {    MyStruct s; s.x = 1; // ok    MyClass c; c.x = 1; // error } struct MyStruct {    int x; }; class MyClass {    int x; };

48 struct / class keyword int main() { //All legal:
No need to typdef the class declaration to avoid using "struct MyStruct" or "class MyStruct". But, it is legal. (May be useful if you want to use the same name for a variable and a class which itself is a bad idea). int main() { //All legal: struct MyStruct s1; class MyClass c1;    MyStruct s2; MyClass c2; }

49 Class Basics - member/static
class List { public:    static int getMaxSize();    int getSize();    static int max_size=1000; //error! (only outside, below) int size=0; //error! (only in ctor, coming slides) }; int List::max_size=1000 //ok. int main() {    List l;    l.getSize();    List::getMaxSize();    l.getMaxSize(); } More about this in the tirgul

50 this static int List::getMaxSize() //no this! {    return this->size; // compile error! return max_size; // ok } int List::getSize() {    return this->size; //ok }

51 Class Basics: Constructors
Initialize the class object upon construction class MyClass { public:    MyClass();    MyClass( int i );    MyClass( double x, double y );    ... }; MyClass a; // Calls 1 MyClass b(5); // Calls 2 MyClass c( 1.0, 0.0 ); // Calls 3 1 2 3

52 Constructors – implicit default ctor
class MyClass { public:    MyClass(); // default ctor.    //... }; //... int main() {    MyClass a; // default ctor. is called    // ...

53 Constructors – implicit default ctor
class MyClass { public:     ... }; int main() {    MyClass a; // default ctor. is called

54 Constructors – implicit default ctor
class MyClass { public:    MyClass(int x); // no default cons. }; int main() {    MyClass a; // complier error – // no default cons. No way to call from one constructor to another one!

55 Destructors Ensure propose “cleanup” when the object is destructed
Use for freeing memory, notifying related objects, etc.

56 Class Basics: Destructors
#include <cstdlib> class MyClass { public:    MyClass();    ~MyClass(); // destructor private:    char* _mem; }; MyClass::MyClass() {    _mem=(char*)malloc(1000); } MyClass::~MyClass() {    free(_mem); } int main() {    MyClass a;    if( ... )    {       MyClass b;           }     }

57 C Interface struct IntList; typedef struct IntList IntList; IntList* intListNew(); void intListFree( IntList* List ); void intListPushFront( IntList* List, int x); void intListPushBack( IntList* List, int x); int intListPopFront( IntList* List ); int intListPopBack( IntList* List ); int intListIsEmpty( IntList const* List); typedef void (*funcInt)( int x, void* Data ); void intListMAPCAR( IntList* List, funcInt Func, void* Data ); Prelude to slide malloc/free vs. new/delete, BUT – also a chance to compare c style interface with c++

58 C++ Class In header file:
private:   struct Node   {       int value;       Node *next;       Node *prev;   };   Node* m_start;  Node* m_end; }; class IntList { public:   IntList();   ~IntList();   void pushFront(int x);   void pushBack(int x);   int popFront();   int popBack();   bool isEmpty() const; PROS and CONS: More structured, "OO" Reveals the private implementation!!!! It is protected from change, but if you want to change the implementation you must change the header file.

59 Classes & Memory allocation
Consider this C++ code main() {    IntList L;     } What is the difference? Compare to C style: main() {    IntList* L = (IntList*)malloc (sizeof(IntList));    free(L) }

60 Classes & Memory allocation
IntList* L = (IntList*)malloc(sizeof(IntList)); Does not call constructor! Internal data members are not initialized free(L); Does not call destructor! Internal data members are not freed What should we do? createObj and freeObj functions

61 new & delete Call destructor Free memory Special operators:
IntList *L = new IntList; Allocate memory Call constructor Return pointer to the constructed object delete L; Call destructor Free memory

62 new Can be used with any type:
int *i = new int; char **p = new (char *); new is a global operator new expression invokes the new operator to allocate memory, and then calls ctor Can be overloaded (or replaced) By default, failure throws exception. Can be changed. See <new> header Replacing – the global operator new() isn't overloaded but special behavior – user defined function will replace (effectively hide) the pre defined. By standard, each c++ implementation should provide a global operator new() function that can be replaced. Overloaded – inside a specific class you can overload the operator for that class.

63 Global operator new (simplified)
void *operator new(size_t size) { void *p; if((p = malloc(size)) == 0) { throw std::bad_alloc; } return p; }

64 New & Constructors class MyClass { public:    MyClass();    MyClass( int i );    MyClass( double x, double y );     }; MyClass* a; a = new MyClass; // Calls a = new MyClass(5); // Calls a = new MyClass( 1.0, 0.0 ); // Calls 1 2 3 1 2 3

65 New & arrays To allocate arrays, use
int n = 4; int *a = new int[10]; // array of 10 //ints IntList *b = new IntList[n]; // array of n IntLists Objects in allocated array must have an argument-less constructor!

66 Allocate array of objects w/o def. cons.
int n = 4; MyClass **arr = new MyClass *[n]; // array of n pointers to MyClass (no // cons. is invoked) for (int i=0;i<n;i++) {    arr[i] = new MyClass (i);    // each pointer points to a MyClass // object allocated on the heap, and // the cons. is invoked. }

67 Delete & array Special operation to delete arrays
int *a = new int[10]; int *b = new int[10]; delete [] a; // proper delete command delete b; // may work, but may // cause memory leak!

68 Free an allocated array of pointers to objects on the heap
int n = 4; for (int i=0;i<n;i++) {    delete (arr[i]);    // invoked the dest. of each MyClass // object allocated on the heap, and // free the memory. } delete [] arr; // free the memory allocated for the // array of pointers. No dest. is invoked


Download ppt "Structs (C) Already seen in tirgul."

Similar presentations


Ads by Google