Lecture04_VariablesExpressionsShortened
Download
Report
Transcript Lecture04_VariablesExpressionsShortened
Variables and Expressions
http://independencescience.com/blog/tvi-tips-4-strategies-to-prepare-a-student-with-visual-impairments-for-success-inscience-and-math-courses/
Outline
I. Base2 & Base16 and its connection to CPU/RAM
II. Variables / Types in C/C++ (we'll see more later)
III. Statements & Expressions in C/C++
IV. Executable file format and the role of the OS
RAM
●
●
●
Recall: Storage for numbers currently being
manipulated
–
Images
–
Text
–
Programs
–
…
Volatile
Made of billions of transistors or capacitors
http://en.wikipedia.org/wiki/File:Siliconchip_by_shapeshifter.pn
Part I
●
●
Bits, Bytes and Nybbles
Base2 (binary) and Base16 (hexadecimal) number
systems
http://scottkantner.com/bits-bytes-and-bandwidth/
Bits
●
A bit is
–
One transistor / capacitor (in a larger Integrated Circuit)
–
Either on or off
●
●
Kind of like a light-bulb
As programmers we
–
don't worry about the physical structure of a bit
–
Think of it as being true (on, 1) or false (off, 0)
http://www.nerditorial.com/newsandopinion/it%E2%80%99s-ablinking-conspiracy.html
Groups of bits
●
●
With one bit, we can store one of two values
–
0 = off
–
1 = on
However, with a group of bits we
–
Can have multiple combinations of on / off's
–
Can assign an (arbitrary) value to each combination
Two bits
●
With two bits, we have...
4 possible combinations
Combination#
(Arbitrary)
Bit1 Bit2
0
0
0
1
0
1
2
1
0
3
1
1
Three bits
●
With three bits we have...
8 possible combinations
Combination#
(Arbitrary)
Bit1 Bit2 Bit3
0
0
0
0
1
0
0
1
2
0
1
0
3
0
1
1
4
1
0
0
5
1
0
1
6
1
1
0
7
1
1
1
Four bits
●
With four bits, we have
16 possible combinations
Combination# (Arbitrary)
Bit1
Bit2
Bit3
Bit4
0
0
0
0
0
1
2
0
0
0
0
0
1
1
0
3
4
0
0
0
1
1
0
1
0
5
0
1
0
1
6
7
0
0
1
1
1
1
0
1
8
1
0
0
0
9
10
1
1
0
0
0
1
1
0
11
12
1
1
0
1
1
0
1
0
13
1
1
0
1
14
1
1
1
0
See a pattern?
●
If we have n bits, we have
2n
possible combinations
●
We can think of this combination as being a
number in the base2 (binary) number system
Comparison to base-10 (decimal)
●
Base-10
–
Digits are 0, 1, 2, 3, 4, 5, 6, 7, 8, and 9
–
Place-values:
–
●
●
Right-most digit (1' place. 10^0)
●
Next right-most digit (10's place. 10^1)
●
Next right-most digit (100's place. 10^2)
●
…
E.g. 3472 is the same as 3*1000 + 4*100 + 7*10 + 2*1
Base-2
–
Digits are 0 and 1
–
Place-values:
●
Right-most digit (1's place. 2^0)
Base10 => Base2 conversion
●
Method I:
1. Come up with the (only) sum of powers-of-two that
equal the original number
2. Create a binary string with
●
1's in the place-values you used in step1.
●
0's everywhere else
●
As many 0's in the higher-place values that you want
–
–
–
E.g. 00000101 is the same values as 101
Just like 0342 is the same as 342 in base-10
Example: 4833
Base10 => Base2 conversion, cont.
●
Method II (An algorithm)
def decimal2binary(base10Num):
n = base10Num
s = ""
while n > 0:
if n is odd:
s = "1" + s
if n is even:
s = "0" + s
n = n / 2 (ignore remainder)
return s
Base16
●
Digits are
–
0, 1, 2, 3, 4, 5, 6, 7, 8, 9
–
Problem: We need some symbols for the other 6!
●
Solution: use the letter symbols A, B, C, D, E, F
–
●
DOESN'T represent text!
For programmers, used as a shorthand for (long)
binary strings
Base16, cont.
Binary Digit
Base-10
equivalent
Base16
0000
0
0
0001
1
1
0010
2
2
0011
3
3
0100
4
4
0101
5
5
0110
6
6
0111
7
7
1000
8
8
1001
9
9
1010
10
A
1011
11
B
1100
12
C
1101
13
D
1110
14
E
Base16, cont.
●
1 base16 (hexadecimal) digit can store the same
range of values as 4 binary digits.
●
An easy way to convert from base2 => base16
●
Example:
1101 0001 1010 0111 1000
D
●
1
C
7
8
(binary)
(hexadecimal)
Hexadecimal values are often written as 0xD1C78
–
To make it clear we have a hex number
–
E.g. is 754 decimal or hexadecimal?
●
Don't know!
Back to computer architecture...
●
The fundamental storage unit is a byte
–
8 bits
●
256 different combinations
●
A kilobyte is 1024 (2^10) bytes
●
A megabyte is 1024 kilobytes (2^20 bytes)
●
A gigabyte is 1024 megabytes (2^30 bytes)
●
Each byte has an address
●
–
Addresses start at 0...
–
...Go up to #bytes-1
So...on a 4GB machine, we'd have address from 0-
Part II
●
Variables in C/C++
–
int
●
–
●
Signed / Unsigned
float (IEEE 754)
A few new printf / cout
features
http://www.wisegeek.org/what-is-a-cardcatalog.htm
Variables
●
●
In our program, we'll nearly-always want to
allocate some memory to store things that our
program is working with. This is a variable.
To allocate a single byte we do something like:
int main()
{
char c;
unsigned char uc;
// Can store values -128 to 127
// Can store values 0 to 255
return 0;
}
●
●
This allocates 1 byte of storage in RAM.
A variable must be declared before using
(unlike Python / MathPiper)
Modifying / using variables
●
We can change the value stored by the variable a
number of ways:
int main()
{
char c = 75;
unsigned char uc;
// Assigning with declaration
c = -15;
uc = c;
// Modifying value
// Copying value of c
//
(sets uc to 241 –
c = 'a';
// Sets c to 97 – why?
//
Hint: 'a' ISN'T a
why?)
string
return 0;
}
Negative numbers
●
A char's bits can be in one of 256 different states
0-255: Just interpret the binary bits as a base-2 number
-128-127: How is this represented?
●
Answer: Two's Complement (or one's
complement)
Two's complement
●
Take the base-10 number 73
1001001 in base-2
●
In two's complement, to represent -73:
–
Invert the bits
–
Add one (in binary) – make sure you do the carrying
0100 1001
+73 in base10
1011 0110
Inverted bits
1011 0111
After adding the one
Two's complement, cont.
●
Q: Why do this?
●
A1: The highest-order bit will be a 1 if negative
●
●
A2: The computer can use the same “ADD”
circuitry (in the ALU part of the CPU) to add
signed and unsigned numbers.
A3: In other schemes (sign-bit, 1's complement),
there are 2 definitions of 0 (-0 and +0).
Two's complement, cont.
(Unsigned) Look at 15 + 49 (which is 64) in binary
0000 1111
(15)
0011 0001 +
(49)
0100 0000
(64)
(Signed) Look at -74 + 29 (which is -45)
1011 0110
(-74 in 2's complement)
0001 1101 + (+29)
1101 0011
The high-order bit is 1 so we know
“Undoing” Two's complement
●
To get the negated number,
–
Add a bit string of all 1's (you'll lose the high values
when carrying)
●
–
Note: this is -1 in two's complement
Invert the result
1101 0011
1111 1111 + Add this
1101 0010
Then invert...
0010 1101
(Same as before)
Thanks to Jeremy McCleese for this one
Integers
●
A char is capable of storing an integer
–
●
But only in the range 0-255 (or -128-127 with two's
complement)
To store a wider range of values, we need more bits
–
Or...group multiple bytes together
C/C++ type
#bytes Range of values
short
2
-215 to +(215 - 1)
unsigned short (or unsigned short int)
2
0 to +(216 - 1)
int
4
-231 to +(231 - 1)
unsigned int
4
0 to +(232 - 1)
long (or long int)
varies
(usually the same as
int)
unsigned long (or unsigned long int)
varies
(usually the same as
unsigned int)
(or short int)
IEEE 754 (float's)
●
Floats are used to store floating-point numbers
–
i.e. those with a decimal part
–
Can only approximate:
●
Many rational numbers
–
–
●
Irrational numbers
–
–
●
1/3 and 1/10 are approximated (as well as any prime denominator
besides 2)
½ can be represented exactly (and ¼, 1/8, etc)
e (2.719...)
π (3.14159...)
Significantly more complex than integers
–
Big range of values
Float's, cont.
●
A float (in IEE754 and most C/C++ compilerss) is
4 bytes
Higest-order bit: sign (0=positive, 1=negative)
Next 8 bits: exponent
Last 23 bits: mantissa (always in the range 1.0 – 2.0)
●
A float constant is represented as:
sign * 2exponent * mantissa
●
Ex. 0.40625 is stored as
+1 * 2-2 * 1.625
●
A good reference: http://www.h-
Floating Point's in C/C++
●
Another type: double and long double
–
doubles are generally 8 bytes (more precision, memory)
–
long doubles are often also 8 bytes (on my C::B it is
12??)
–
Try this:
void main()
{
int numBytes;
float f;
numBytes = sizeof(float);
numBytes = sizeof(long double)
numBytes = sizeof(f);
}
Floating Points in C/C++
●
Another code snippet...
int main()
{
int i = 9;
float f;
double d;
const float rate = 0.15f;
f = 3.14f;
f
f
f
d
=
=
=
=
// Identifies 3.14 as a float constant
//
(vs. a double constant)
i;
// Implicit type-cast from int to float
(float)i;
// Explicit (c-style) type-cast from int to float
1.275693e-5f;// Scientific notation float constant (1.27..x10^-5)
76.123e12;
// Scientific notation double constant (76.123x10^12)
rate = 0.16f;
return 0;
}
// ERROR!
Strings
●
This'll be our next topic – after we look at arrays.
More cmd-line output commands
int i = 9;
float f;
// Cstyle
printf("C STYLE\n=======\n");
f = 3.75f;
printf("The float is %0.1f\n", f);
f = 0.153;
printf("The float is %0.1f\n", f);
printf("The zero-padded float %015.2f\n", f);
printf("The padded float
%15.2f\n", f);
printf("The zero-padded int
%015d\n", i);
printf("The padded int
%15d\n\n", i);
More cmd-line output commands
int i = 9;
float f;
// C++ style
cout << "C++ STYLE" << endl << "=========" << endl;
f = 3.75f;
cout.precision(1);
cout.setf(ios::fixed);
cout << "The float is " << f << endl;
f = 0.153;
cout << "The float is " << f << endl;
cout.setf(ios::right | ios::fixed);
cout.precision(2);
cout.fill('0');
cout << "The zero-padded float ";
cout.width(15);
// Only affects next cout.
cout << f << endl;
cout.fill(' ');
cout << "The padded float
";
cout.width(15);
cout << f << endl;
cout << "The zero-padded int
";
cout.width(15);
cout.fill('0');
cout << i << endl;
cout << "The padded int
";
cout.width(15);
cout.fill(' ');
cout << i << endl;
Part III
●
Statements
●
Building-blocks of statements
http://barkersbite.blogspot.com/2010/10/alexbox.html
Statements
●
●
A single “command” in C/C++
–
May be made of several parts
–
Sometimes quite complex
Made of combinations of:
–
Variable Declarations
–
Expressions
–
●
Operators
●
Constants
●
Values
●
Function Calls
Structure Definitions (classes, struct's, etc.)
Variable Declarations
●
We've seen these already...
–
Usually placed at the top of a code block
–
In C++ you can place them almost anywhere.
int main()
{
int i, w=9, z;
float j = 3.1;
i = 0;
float q = 9.0;
while (i < 5)
{
float k = j * i;
i++;
}
}
// C++ only
Operators
●
Three types
–
Unary (++ and -- and – (negation))
–
Binary (+, - (subtraction), *, /, %, >>, <<, |, &, ~, ^, =)
●
–
(There are more)
Ternary ( ?: )
Unary operators
int main()
{
int i, j, k = -15;
float f;
i = 5;
i++;
++i;
j = i++;
j = ++i;
i--;
f = 3.1f;
f++;
i is now holding a 6
i is now holding a 7
i is now holding an 8, j has a 7
i is now holding a 9, j has a 9
now i's holding a 8
i = -j;
// The unary operator again
j = 22;
// 0000 ... 0001 0110 in binary
k = ~j;
// bitwise INVERT. Bits in k are the "opposite" of j.
// 1111 .... 1110 1001
(-23 decimal)
return 0;
}
//
//
//
//
//
// Note the '-' here is a unary operator
Binary Operators
●
The usual operators:
+
-
*
/
Type of operands
affects the result of the operator
Note
long double
(the other operand is implicitly converted to be of
double
the “bigger” type)
Type●
float
bigger
unsigned long / long
A unsigned long is picked if both values are positive.
Otherwise, a long is used.
unsigned int / int
“ditto”
unsigned short / short
“ditto”
unsigned char / char
“ditto”
Binary Operators, cont.
●
Assignment
–
Uses the equal (=) operator
–
The left-hand operand must always be a variable
–
The right-hand side can be an arbitrarily complex
expression
●
–
Must evaluate to a value
Implicit Type Conversion
●
For built-in types, done automatically
●
May result in a loss of data
int
main()
{
int i, j;
float f;
char c;
i = 500;
j = 301;
f = i + j;
c = i + j;
return 0;
}
// f will store 801.0f
// c will store 33
Binary Operators, cont.
●
Modulo
–
The “remainder” operator
–
Only works with integer types (char, short, int, …)
int main()
{
int i, j;
i = 10 % 3;
// i will hold a 1
i = -15 % 2;
// i will hold a -1
/* … other code (changing i and j) … */
i = i % j;
// i will be set to the remainder of i / j
/* ...more code...*/
if (i % 2 == 0)
{
// We'll get into this block if i is even
}
return 0;
}
Binary Operators, cont.
●
Bitwise operators (&, |, ~, ^)
–
Only work with integer types
–
Manipulate the binary number encoded in the integer.
int main()
{
int i, j, k;
i = 0x00000005;
j = 22;
// A hexadecimal constant. 0000 ... 0000 0101 in binary
//
0000 ... 0001 0110 in binary
k = i & j;
// bitwise AND (set bits in k to 1 if they are 1 in
//
BOTH i AND j)
//
0000 .... 0000 0100
(4 decimal)
// bitwise OR (set bits in k to 1 if they are 1 in
//
EITHER i OR j)
//
0000 .... 0001 0111
(23 decimal)
k = i | j;
k = i ^ j;
return 0;
}
// bitwise XOR (exclusive OR). Sets bits in k to 1
// if they are different in j and k
//
0000 .... 0001 0011
(19 decimal)
Binary Operators, cont.
int main()
{
int i, j, k;
i = 0x00000005;
j = 22;
// A hexadecimal constant. 0000 ... 0000 0101 in binary
//
0000 ... 0001 0110 in binary
k = j >> 1;
// bitwise RSHIFT (shifts all bits to the right
//
(they fall off the "edge"))
//
0000 .... 0000 1011
(11 decimal)
//
Note: equivalent (but faster) than k = j /
//
0000 .... 0000 0101
(5 decimal)
//
Note: equivalent (but faster) than k = j /
//
0000 .... 0000 0010
(2 decimal)
//
Note: equivalent (but faster) than k = j /
// bitwise LSHIFT (shifts all bits to the left
//
(adding 0's to the right))
//
0000 .... 0010 1100
(44 decimal)
//
Note: equivalent (but faster) than k = j *
k = j >> 2;
k = j >> 3;
k = j << 1;
return 0;
}
2;
4;
8;
2;
Ternary Operator
●
Syntax:
[boolean-expr] ? [true-expr] : [false-expr]
int main()
{
int i, j, k;
cout << “Enter two integers: “;
cin >> i >> j;
// Using the ternary operator to find the square of the bigger
k = i > j ? i * i : j * j; // We'll cover comparison operators next
time.
return 0;
}
Order of operations
●
●
Like in math, some operators are evaluated first
We can change the order of operations by using
parentheses
1. ()
2. ~ - (unary) & (address-of)
3. *
/
%
4. + (addition)
5. <<
- (subtraction)
>>
6. & (bitwise and)
7. ^ (bitwise XOR)
++
Performed
sooner
--
Part IV
●
Executable File Format
Major sections
Stack
Stack: All variables we've been using so far exist
here. Later (when we get to functions), we'll see it
also is integral in function calls.
Heap
Heap: A different way to allocate variables / data.
We'll see this when we get to dynamic allocation
(malloc & new).
Global Variables
GlobalVariables: A third way to allocate variables.
These are in existence the entire duration of the
program's run.
Import Table
Import Table: Used to call OS functionality (in
DLL's or shared libraries). We'll look at this when
we import external libraries (e.g. OpenGL).
Text: Holds the machine code instructions
(encoded as numbers).
Text