Variable
types
Enumerated
Data Type:
keyword:
enum
an enumerated
data type is that you are counting all the objects. It is similar to a
set.
Anonymous
enumerated data type:
Example:
enum
{LIST_OK, LIST_NO_MEM,…..}
you don't need
to specify numbers for the error codes. That is done automatically.
The first one is automatically assigned the value of "0" and the next on
"1" and so on. (LIST_OK = 0, LIST_NO_MEMORY = 1, …)
Later on in the
program:
int
err;
.
.
err
= LIST_OK;
enumerations can
also be given names.
Named
enumerated data type
Example:
enum ErrorCode {LIST_OK, LIST_NO_MEM, …};
This is a
completely new data type. Now you can create functions that return
ErrorCode's
ErrorCode err = LIST_OK;
You can also
choose your own values for enumerations:
Example:
enum set{A=8, B=10, C, D};
if a value is
not set, the value takes up where you last specified a value. For
instance, in the example above, C=11 and D=12 because the last value you
specified was for B.
Another
interesting fact is that you can double-up values.
enum
set{A=-1, B, C, D=0};
B, by default is
given the value "0" but you can still specify that D also has the value of
"0".
How can this be
useful to us in a specific way? Think about the situation when you have a
class named Date.
class Date
{
public:
enum Month {Jan=1, Feb, Mar, Apr,…
Dec};
int day;
Month month; // must
place after enum setting
int year;
set_date(Month, int, int);
};
Now, if someone
wants to use these month symbols outside the class method, it would be done in
the following manner:
Date d;
d.set_date(Date::Apr, 17, 2001);
With this
information we can definitely get around the array size problem we had earlier
where we declared a const int outside the class.
Example:
(recall the String class we created)
class String
{
enum {max_size = 100};
// note that it is private
char data[max_size];
public:
func();
};
/**************************************************************/
String::func()
{
. .
.
a =
max_size; // use just as expected
}
Note that the
enumerated max_size is not an L-value and you cannot assign values to
them
Ways of
allocating memory:
automatic
variables:
keyword:
auto
automatic
variables are declared but memory for those variables does not exist until that
function is called. When the function is called that contains them, the
memory will be allocated. This is why we can get away with recursion,
because every time a function is called, it sets up a new copy of those
variables
Example:
Standard implementation
Alternate
Implementation
func()
func()
{
{
int a;
auto
int a;
int *p;
auto
int *p;
}
}
global
variables:
Global variables
are variables you can have outside of a function. They are available to
everybody.
global variables
are static variables.
local
variables:
variables that
are inside a function are called local variables and can only be used within the
scope of the function. They are dynamically created when the function is
called. The is a very subtle difference between this and the dynamic
memory allocation when you call new or malloc.
static
variables:
a static
variable is a global variable which is set up at the beginning of a program.
They have no idea who is going to use them first. They are called
static because their allocation is not dynamically changed.
If you set g=0 in A.C you want to be able to print out and
set g from within B.C You want a global variable available to both A.C and
B.C so that it can be shared back and forth. The only problem is… Where is
the memory for this? When you compile and create object files for A and B,
it says that there is a global variable in A.C and so it creates memory for it.
Likewise in B.C the compiler creates static memory for the variable.
So, both A.o and B.o have memory set aside for g. Which memory is
correct??
As it turns out, both are correct. This means that
when we make changes to g in A and then do the same thing in B, B is going to
access something entirely different. How do we get around this
problem?
Two
keywords: are available in C and C++
extern -
static -
extern - keyword that you put in front of a variable
declaration which tells the compiler there is a symbol of this type but the
memory is somewhere else.
so in A.h
declare g as: extern int
g;
now when A.C
sees it and B.C sees it, they don't allocate memory automatically.
**Note
that you must have memory declared in one and
only one of the source files
also.
You would think
that this would be a compiler error because you are declaring the variable in
both the A.h and the A.C file but in this special case it is not.
static - when applied to a global variable
means
that this symbol
can only be seen inside this source
code file.
is also useful when you want a variable inside a
function to
preserve it's value between the times
it gets called
and in the function is the only place
that you are
going to use it. All variables in a function
are destroyed
when you leave the function. BUT if you
declare the
variables inside the function as static, they
be used just
like any other variable with the exception
that the memory
associated with that function is in the static memory space. In other
words, the memory that is initialized when the program is started and not when
the function is called. It's like a global variable but that symbol is
valid only within that function. It will only be initialized
once.
if you want a
function such as e( ) to be made unseen by any other function including source
code that has included the M.h file, you need to make it a static
function.
Example of
the use of static:
say that you
have a function called f( );
f()
{
int a;
static int b;
.
.
}
memory
associated with the function symbol is valid only in the function.
initializing it
here (b=0) will initialize it only once. How does this effect us with
classes?
Example:
class W
{
static int a; // takes
this member and allocates it out of static
//
memory before the program is started
};
This will
allocate static memory before the program runs. You may wonder how it does
this if you don't know how many instances of the variable you will have.
The answer is you don't . This member has only one instance of that
member made for the class.
Note that there
is only one instance of 'a' for the entire class. All instances of the
class have the same 'a' in common. Whenever anyone accesses that member
'a' they will get the same value as anyone else who accesses
it.
But there is
a problem. You can't initialize it within a class so how do you initialize
it?
If you declare a
static data member of a class, you need to allocate memory for it.
Before the constructor and the destructor in your source code
file:
static int W::a = 0; // allocates memory and
initializes
If you are
dealing with constants you can declare it as follows:
class W
{
static const int SIZE = 50;
int ar[SIZE];
…
};
Note: this is the ONLY time you can
initialize
a member within a class. ( if it is a static
const)
You can
initialize within a class if you declare it as a const int. The SIZE will
then remain in the class. This declares a constant variable without having
be a global constant. This is a better way than using enumeration for
declaring constants.
static says that
nobody outside this source code file knows about this instance of the
variable.
Sample code for this section to be posted on the
official course site under test13.C and
test13a.C
You can't have a
const int in a class because it will be initialized for every instance in class.
You can't do this. But if you declare it as static… for
example:
static const int SIZE = 50;
then it allows
you to have the constant variable declared within the class without being a
global const int. If you code:
static int a: //
need to declare to make memory
static const int a; created here
.
.
enum {SIZE = 50};
Key Note:
Memory for static variables is created when program is run not when
function is called
Static variables don't go away when you leave the
function.
|