Lecture01c_cpp_reviewx

hungryhorsecabinΛογισμικό & κατασκευή λογ/κού

14 Δεκ 2013 (πριν από 4 χρόνια και 18 μέρες)

83 εμφανίσεις

Lecture 01c:
C++ review

Topics:


static arrays


array / pointer connection


dynamic arrays (and pointers)


2D arrays

Overview


Arrays are a group of
contiguous
,
homogeneous

data.


We can get around both restrictions with [our
own] data structures


Two types:


statically allocated
(the "easier" kind): we know at
compile time how many elements will be in the
array.


dynamically allocated
: we don't


Example: reading an image from disk => memory

PartI
: Static arrays

double
enemyDistances
[6]; // Use
const

int

or macros?

Enemy enemies[6];



// A user
-
defined class


enemyDistances
[0] = 15.7;

enemyDistances
[1] =
enemyDistance
[2] * 2;

cout

<<
enemyDistances
[3] <<
endl
;

// output?

cout

<<
enemyDistances

<<
endl
;

// output?

Scope


We'll talk more about this after functions…


Basically
scope

defines:


where a particular name is valid


when that name "dies"


C/C++ use
block

scope

Scope, cont.


All "normal" variables are "destroyed" when
control leaves their scope.


This includes statically allocated arrays.

int

main()

{

int

x;

float sizes[4];


cin

>> x;


if (x > 10)


{



double x;


// Note: "name
-
masking"



// …


}

}

Part II: Arrays and pointers


[Look at the memory diagram for last
example].


Now add…

double
enemyDistances
[6]; // Use
const

int

or macros?

double d;

double * p;

enemyDistances
[0] = 15.7;

p = &d;




*p = 17.6;

p = &
enemyDistances
[5];


*p = 9.1;

p =
enemyDistances
;


*p = 3.3;

// Error?

cout

<< p <<
endl
;

cout

<<
sizeof
(double) <<
endl
;

cout

<< p + 2 <<
endl
;

*(p + 2) = 11.2;

p[2] = 11.2;


// Exactly the same!

Part III: Dynamic allocation


Some differences


Memory allocation is from the
heap
; "normal"
allocation (static) is from the
stack
.


The memory stays allocated until we free it


No automatic cleanup when we leave the scope.


OK…the compiler / OS probably clean up after the
program
ends, but…


It must be done through pointers.


Note: there are two (slightly different) syntaxes:


array allocation


single allocation

Example

fstream

fp
;


int

width, height;


char * data = NULL;


fp.open
("my_img.jpg",
ios
::in |
ios
::binary);


fp.seekg
(8,
ios_base
::beg); // I'm fudging jpeg format...


fp.read
((char*)&width, 4); // Note the (C
-
style) cast


fp.read
((char*)&height, 4);


fp.seekg
(4,
ios_base
::cur);


data =
new

char[width * height];


fp.read
(data, width * height); // No cast needed


fp.close
();


// ... Use data ...




// De
-
allocate data


if (data) // Note: NULL = 0 = false


delete []
data;

Dynamic allocation
(of singular types)


Note: you can allocate a single item on the
heap


not super useful for "standard" types


Very useful for objects


The syntax is a bit different

double *
single_double

= NULL;


single_double

=
new double
;


// No brackets

*
single_double

= 9.3;

cout

<< *
single_double

<<
endl
;

delete
single_double
;



// No brackets

Part IV: 2D arrays


A "normal" array (dynamic and static) are like
a 1
-
dimensional array.


You can also represent 2 (or higher)
dimensional data


Two options:


Create a "flat" array and convert row/col numbers
to an offset.


Let the compiler generate these offsets for you.

Examples


Let's say we want to store this data

4
.
0

6
.
3
2
.
1
1
.
9
0
.
0

5
.
8


Static array, declared + initialized

float
static_arr
[2][3] = {{4.0f,
-
6.3f, 2.1f},




{
1.9f, 0.0f,
-
5.8f}};

for (
i
=0;
i
<2;
i
++)

{


for (j=0; j<3; j++)



cout

<<
static_arr
[
i
][j] << " ";


cout

<<
endl
;

}


Static array, declared, then initialized

float static_arr2[2][3];

static_arr2[0][0] = 4.0f;

static_arr2[0][1] =
-
6.3f;

static_arr2[0][2] = 2.1f;


static_arr2[1][0] = 1.9f;

static_arr2[1][1] = 0.0f;

static_arr2[1][2] =
-
5.8f;

Examples, cont.


dynamically allocated [Show memory diagram]

float **
dynamic_array
;

dynamic_array

= new float*[2];

dynamic_array
[0] = new float[3];

dynamic_array
[1] = new float[3];


dynamic_array
[0][0] = 4.0f;

dynamic_array
[0][1] =
-
6.3f;

dynamic_array
[0][2] = 2.1f;


dynamic_array
[1][0] = 1.9f;

dynamic_array
[1][1] = 0.0f;

dynamic_array
[1][2] =
-
5.8f;


// Use the same way as the static array before


delete []
dynamic_array
[0];

delete []
dynamic_array
[1];

delete []
dynamic_array
;

Examples, cont.


Dynamically allocated "flat" array

float *
dynamic_flat

= NULL;

int

i
;


dynamic_flat

= new float[2 * 3];


dynamic_flat
[0 * 3 + 0] = 4.0f;


dynamic_flat
[0 * 3 + 1] =
-
6.3f;


dynamic_flat
[0 * 3 + 2] = 2.1f;



dynamic_flat
[1 * 3 + 0] = 1.9f;


dynamic_flat
[1 * 3 + 1] = 0.0f;


dynamic_flat
[1 * 3 + 2] =
-
5.8f;




for (
i
=0;
i

< 3 * 2;
i
++)


{



cout

<<
dyamic_flat
[
i
];



if (
i

> 0 &&
i

% 3 == 0)

cout

<<
endl
;



else




cout

<< " ";


}



delete []
dynamic_flat
;