CMPSC 311 – Introduction to Systems Programming
Types, Structs, and Unions
Professors:
(Slides are mostly by Professors Patrick McDaniel and )
Copyright By PowCoder代写 加微信 powcoder
CMPSC 311 – Introduction to Systems Programming
• A data type is an abstraction that allows a programmer to treat different memory ranges as they were different classes (types) of data
• e.g., integers, real numbers, text, records, etc.
// This is all just allocating memory with // implicit/explicit sizes and values short int si = 9;
long int li = 1234567890L;
float f = 3.14;
double d = 12324567890.1234567; char c = ‘a’;
char *ptr = &si;
Insight: a variable name simple acts as an alias for a memory range.
CMPSC 311 – Introduction to Systems Programming
• The compiler uses type information in order to determine how to apply the logical operations defined by the code
• Defines how different variables can be operated on, and ultimately what machine instructions are generated and executed
// Is this legal?
double one = 3.24, two = 4.5, res1;
int three = 3, four = 4059, res2;
// Are the ISA instructions for these two operations the same?
res1 = one + two;
res2 = three + four;
All programming languages use a type system to interpret code.
CMPSC 311 – Introduction to Systems Programming
• Programming languages are strongly or weakly “typed” (or some in between) • Such distinctions refer to the quality of the language in
dealing with ambiguity in types and usage
• C is weakly typed, which leads to great flexibility
• Also leads to a lot of bugs ..
• Q1: what value is output from the following code? • Q2: was that what the programmer intended?
// How is “one” treated?
double one = 3.24;
if ( one / 3 == 1 ) {
printf( “true” );
printf( “false” );
Intuition: In general, a strongly typed language won’t compile if variables of a different type are passed as parameters, compared, etc. Conversely, a weakly typed language (like C) will do its best to coerce (convert) it to be the correct type.
CMPSC 311 – Introduction to Systems Programming
• The code actually prints “false” because the
3 is turned into a floating point number (3.0)
// How is “one” treated?
double one = 3.24;
if ( one / 3 == 1 ) {
printf( “true” );
printf( “false” );
and the 1 is converted to (1.0). //
• Q2: was that what the programmer intended?
• You need to be careful in dealing with .. • Expressions (e.g., one + 1)
• Parameter passing (e.g., f(one))
• Comparisons (e.g., one == 1)
Compiled expression: (3.24/3.0) == (1.0)
CMPSC 311 – Introduction to Systems Programming
Static vs Dynamic Typing
• No accepted definition of strong vs weak typing
• Another aspect of typing:
• Static typing – this occurs when the type of
data is decided at compile time, and type conversion occurs at that time
• Examples: C, C++, Java, …
• Dynamic typing – this occurs when the run- time environment dynamically applies types to variables as need
• Examples: Perl, Python, Ruby
• Pros and cons of typing approaches
Clojure Python
Strongly Typed
Erlang PHP
Perl JavaScript
Weakly Typed
CMPSC 311 – Introduction to Systems Programming
Type casting
• Q: But what if you want to control the way the type is converted?
• A: You can annotate a type conversion explicitly using type casting
// Now what?
double one = 3.24;
if ( (int)one / 3 == 1 ) {
printf( “true” );
• Syntax: • where
(type)variable • type is a type to covert to
printf( “false” );
• variable is the variable to be converted
• by converting it one to an int, the semantics of
the expression change to be all integers
Compiled expression: (3/3) == (1)
CMPSC 311 – Introduction to Systems Programming
Legal Type Casting
int main(void) {
short int si = 9;
long int li = 1234567890L; float f = 3.14;
double d = 12324560.1234567; char c = ‘a’;
char *ptr = &si;
printf(“short int %d %f %p\n”, (int)si, (float)si, (char *)si); printf(“long int %d %f %p\n”, (int)li, (float)li, (char *)li); printf(“float %d %f (ERR)\n”, (int)f, (float)f); printf(“double %d %f (ERR)\n”, (int)d, (float)d);
printf(“char %d %f %p\n”, (int)c, (float)c, (char *)c); printf(“ptr %d (ERR) %p\n”, (int)ptr, (char *)ptr); return 0;
./typecast
short int 9 9.000000 0x9
long int 1234567890 1234567936.000000 0x499602d2 float 3 3.140000 (ERR)
double 12324560 12324560.000000 (ERR)
char 97 97.000000 0x61
ptr -716365630 (ERR) 0x7fffd54d20c2
CMPSC 311 – Introduction to Systems Programming
Defining types: typedef
• The C typedef key word is a way of extending the C type system, i.e., to declare new new types for the compiler to recognize and use
• Syntax: typedef [old type] [new type];
• old type is a type definition suitable for declaration • new type is the type to be added
• Example:
typedef unsigned char bitfield;
CMPSC 311 – Introduction to Systems Programming
Using user-defined types
• You can use the new type anywhere you use built in types: // Type Declaration
typedef unsigned char bitfield;
// Return values and function parameters
bitfield myFunction( bitfield x, int y ) {
// Local variables
bitfield z;
float a; …
// Type casting
return( (bitfield)1 ); }
Note: the compiler treats the new type exactly as the old type (the new name acts simply as an alias for the original type)
CMPSC 311 – Introduction to Systems Programming
Programming 101
• Q: When should you define your own types?
• A: you are working on a system that • will have a lot of code …
• last a long time …
• need to be ported …
• have multiple revisions …
• have a maintenance life time … • rely on standards …
• System-specific types afford you flexibility to alter the foundational data structures and types quickly and apply to large code bases.
CMPSC 311 – Introduction to Systems Programming
Structures
• A structure is an organized unit of data that is treated as a single entity (variable)
• Can be defined like any other variable
• Have an implicit “type” (whether typedef-ed or not)
• Syntax • Where
struct { [definition] } [variable(s)];
• definition is the layout of the structure as list of variable definitions (these variable
parts of the struct definition are called fields)
• variable(s) are (one or more) variables which have the type structure
CMPSC 311 – Introduction to Systems Programming
A Basic Example
// Vehicle structure
char name[128]; // Make and model
int mileage; // The current mileage
} gremlin, cayman, cessna180, montauk;
CMPSC 311 – Introduction to Systems Programming
Referencing fields in a C struct
• The period “.” is used to reference the fields of the struct
// Vehicle structure
char name[128]; // Make and model
int mileage; // The current mileage
} gremlin, cayman, cessna180, montauk;
// Accessing the contents of the struct
strcpy(cayman.name, “My favorite car”); // strcpy will be covered later cayman.mileage = 1240;
CMPSC 311 – Introduction to Systems Programming
Enumerated types are useful …
• Recall that enum allows you to associate integer values with names
•
•
} variable;
SUNDAY = 0, MONDAY = 1, TUESDAY = 2, WEDNESDAY = 3, THURSDAY = 4, FRIDAY = 5, SATURDAY = 6
} daysOfWeek;
CMPSC 311 – Introduction to Systems Programming
Enumerated types are useful …
• Note that the
• Compiler will assign integers to these values
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
} daysOfWeek;
enum {
} variable;
CMPSC 311 – Introduction to Systems Programming
Enumerated types are useful …
• You can use the names in any place that you would use an integer.
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
} daysOfWeek;
int x = MONDAY;
int y = TUESDAY * FRIDAY;
if (day == SATURDAY) {
int func(int x); … func(TUESDAY);
CMPSC 311 – Introduction to Systems Programming
Structures can be complex
// Vehicle structure
AUTOMOTIVE = 0, // Automobile or equivalent AERONAUTICAL = 1, // Airplane, rotorcraft, ..
char name[128];
= 2, // Boat or similar
// Make and model
// The current milage
cayman.type = AUTOMOTIVE;
if (cayman.type == AUTOMOTIVE) {
printf(“This is a car\n”); }
int milage;
} gremlin, cayman, cessna180, montauk;
// Example
CMPSC 311 – Introduction to Systems Programming
Structures can be nested
// Vehicle structure
AUTOMOTIVE = 0, // Automobile or equivalent
AERONAUTICAL = 1, // Airplane, rotorcraft, ..
MARINE = 2 } type;
char name[128];
int milage;
int cylinders; int horsepower; int hours_smoh;
// Boat or similar
// Make and model
// The current milage
// The number of cylinders
// The total horsepower
// Hours since last major overhaul // Engine Specification/history
} gremlin, cayman, cessna180, montauk;
// Example cayman.engine.cylinders = 6; cayman.milage = 1240;
CMPSC 311 – Introduction to Systems Programming
• A union is a way to overlay different data structures over the same memory region
• selectively interpret the data in place
union { [definition] } [variable(s)]; • definition is the list of alternate data items
• variable(s) are (one or more)
char vin[17]; // Vehicle ID (car)
char tail_number[8]; // Tail number (airplane) char hull_id[12]; // Hull ID (boat)
} vehicle_id; // The vehicle identifier
CMPSC 311 – Introduction to Systems Programming
char vin[17]; // Vehicle ID (car)
char tail_number[8]; // Tail number (airplane) char hull_id[12]; // Hull ID (boat)
} vehicle_id; // The vehicle identifier
// Example
strcpy(vehicle_id.vin, “123456”); // strcpy will be covered later printf(”%s\n”,vehicle_id.vin); //prints“123456” vehicle_id.tail_number = “F-BOZQ”; printf(”%s\n”,vehicle_id.vin); //prints“F-BOZQ” printf(“Size:%lu\n”, sizeof(vehicle_id)); // prints “17”
CMPSC 311 – Introduction to Systems Programming
Bringing it together
• This is a really ugly structure …
// Vehicle structure
AUTOMOTIVE = 0, // Automobile or equivalent AERONAUTICAL = 1, // Airplane, rotorcraft, ..
MARINE } type;
char name[128];
int milage;
// Boat or similar
// Make and model
// The current milage
// The number of cylinders
// The total horsepower
// Hours since last major overhaul // Engine Specification/history
int cylinders;
int horsepower;
int hours_smoh;
} engine; union {
char vin[17];
char tail_number[8];
char hull_id[12];
// Vehicle ID (car)
// Tail number (airplane)
// Hull ID (boat)
} vehicle_id;
} gremlin, cayman, cessna180, montauk;
// The vehicle identifier
CMPSC 311 – Introduction to Systems Programming
This is where types come in …
// Define the vehicle information
typedef enum {
AUTOMOTIVE
AERONAUTICAL
} VEHICLE_TYPE;
= 0, // Automobile or equivalent = 1, // Airplane, rotorcraft, ..
typedef struct {
int cylinders; // int horsepower; // int hours_smoh; //
} ENGINE_INFO; //
typedef union {
char vin[17];
char tail_number[8]; char hull_id[12];
} VEHICLE_IDENT;
// Vehicle structure
typedef struct {
char name[128];
int milage;
VEHICLE_TYPE type; ENGINE_INFO engine; VEHICLE_IDENT vehicle_id;
} VEHICLE;
// Now define the variables
// Make and model
// The current milage
// The type of vehicle
// Engine specification/history // The vehicle identification
// Boat or similar
The number of cylinders
The total horsepower
Hours since last major overhaul Engine specification/history
// Vehicle ID (car)
// Tail number (airplane) // Hull ID (boat)
// The vehicle identifier
VEHICLE gremlin, cayman, cessna180, montauk;
CMPSC 311 – Introduction to Systems Programming
Accessing fields by pointer (dereferencing)
• When handling a pointer to a struct, the fields are accessed with the “->” operator instead of the “.”
VEHICLE cayman;
VEHICLE *vehicle = &cayman; strcpy(vehicle->name, “2013 Porsche Cayman S”); vehicle->engine.cylinders = 6;
CMPSC 311 – Introduction to Systems Programming
Conditional Operator
• Consists of two symbols “?” and “:” used as follows:
• Read as “if expr1 then expr2 else expr3” • expr1 is evaluated first
expr1 ? expr2 : expr3
• if its value isn’t zero, then the result is the evaluation of expr2 • else the result is the evaluation of expr3
int i = 1, j = 2, k;
k = i > j ? i : j;
k = (i >= 0 ? i : 0) + j;
• Common usage in printf
if (i > j)
printf(“%d\n”, i);
printf(“%d\n”, i);
printf(“%d\n”, i > j ? i : j);
CMPSC 311 – Introduction to Systems Programming
Working with structs
• Other coding topics : what is going on with the multiline print string and “?”
expressions?
VEHICLE *vehicle = &cayman;
printf( “*** Vehicle Information **\n”
“Name : %s\n”
“Milage : %u\n”
“Vehicle type : %s\n”
“Cylinders : %u\n”
“Horsepower : %u hp\n”
“SMOH : %u hours\n”
“VIN : %s\n”, vehicle->name,
vehicle->milage,
(vehicle->type == AUTOMOTIVE) ? “car” :
(vehicle->type == AERONAUTICAL) ? “airplane” : “boat”, vehicle->engine.cylinders,
vehicle->engine.horsepower,
vehicle->engine.hours_smoh,
(vehicle->type == AUTOMOTIVE) ? vehicle->vehicle_id.vin :
(vehicle->type == AERONAUTICAL) ? vehicle->vehicle_id.tail_number : vehicle->vehicle_id.hull_id );
CMPSC 311 – Introduction to Systems Programming
Working with structs
• Other coding topics : what is going on with the multiline print string and “?”
expressions?
VEHICLE *vehicle = &cayman;
printf( “*** Vehicle Information **\n”
“Name : %s\n”
“Milage : %u\n”
“Vehicle type : %s\n”
? “car” : hp
e type : car
hicle->typ
ngine.cylin
N vehicle->engine.horsepower,
Porsche Cayman S
TICAL) ? “airplane” : “boat”,
vehicle->engine.hours_smoh,
(vehicle->type == AUTOMOTIVE) ? vehicle->vehicle_id.vin :
(vehicle->type == AERONAUTICAL) ? vehicle->vehicle_id.tail_number : vehicle->vehicle_id.hull_id );
H4TB2H26CC00000
CMPSC 311 – Introduction to Systems Programming
How is the memory laid out?
#define MEM_OFFSET(a,b) ((unsigned long)&b)-((unsigned long)&a) // Print out the values of the fields
printf( ” SZ Addr Off\n” ); printf( “cayman %3lu %p 0x%02lx\n”,
sizeof(cayman), &cayman, MEM_OFFSET(cayman,cayman) ); printf( “cayman.name %3lu %p 0x%02lx\n”,
sizeof(cayman.name), &cayman.name, MEM_OFFSET(cayman,cayman.name) ); printf( “cayman.milage %3lu %p 0x%02lx\n”,
sizeof(cayman.milage), &cayman.milage, MEM_OFFSET(cayman,cayman.milage) ); printf( “cayman.type %3lu %p 0x%02lx\n”,
sizeof(cayman.type), &cayman.type, MEM_OFFSET(cayman,cayman.type) ); printf( “cayman.engine.cylinders %3lu %p 0x%02lx\n”, sizeof(cayman.engine.cylinders), &cayman.engine.cylinders,
MEM_OFFSET(cayman,cayman.engine.cylinders) );
printf( “cayman.engine.horsepower %3lu %p 0x%02lx\n”,
sizeof(cayman.engine.horsepower), &cayman.engine.horsepower,
MEM_OFFSET(cayman,cayman.engine.horsepower) );
printf( “cayman.engine.hours_smoh %3lu %p 0x%02lx\n”,
sizeof(cayman.engine.hours_smoh), &cayman.engine.hours_smoh,
MEM_OFFSET(cayman,cayman.engine.hours_smoh) );
printf( “cayman.vehicle_id.vin %3lu %p 0x%02lx\n”,
sizeof(cayman.vehicle_id.vin), &cayman.vehicle_id.vin,
MEM_OFFSET(cayman,cayman.vehicle_id.vin) );
printf( “cayman.vehicle_id.tail_number %3lu %p 0x%02lx\n”,
sizeof(cayman.vehicle_id.tail_number), &cayman.vehicle_id.tail_number,
MEM_OFFSET(cayman,cayman.vehicle_id.tail_number) ); printf( “cayman.vehicle_id.hull_id %3lu %p 0x%02lx\n”,
sizeof(cayman.vehicle_id.hull_id), &cayman.vehicle_id.hull_id, MEM_OFFSET(cayman,cayman.vehicle_id.hull_id) );
CMPSC 311 – Introduction to Systems Programming
How is the memory laid out?
#define MEM_OFFSET(a,b) ((unsigned long)&b)-((unsigned long)&a) // Print out the values of the fields
printf( ” SZ Addr Off\n” ); printf( “cayman %3lu %p 0x%02lx\n”,
sizeof(cayman), &cayman, MEM_OFFSET(cayman,cayman) ); printf( “cayman.name %3lu %p 0x%02lx\n”,
sizeof(cayman.name), &cayman.name, MEM_OFFSET(cayman,cayman.name) );
printf( “cayman.milage %3lu %p 0x%02lx\n”,
SZ Addr Off
sizeof(cayman.milage), &cayman.milage, MEM_OFFSET(cayman,cayman.milage) );
cayman 160 0x601080 0x00
printf( “cayman.type %3lu %p 0x%02lx\n”, sizeof(cayman.type), &cayman.type, MEM_OFFSET(cayman,cayman.type) );
cayman.name 128 0x601080 0x00
printf( “cayman.engine.cylinders %3lu %p 0x%02lx\n”, cayman.milage 4 0x601100 0x80
sizeof(cayman.engine.cylinders), &cayman.engine.cylinders,
cayman.type 4 0x601104 0x84
MEM_OFFSET(cayman,cayman.engine.cylinders) );
cayman.engine.cylinders 1 0x601108 0x88
printf( “cayman.engine.horsepower %3lu %p 0x%02lx\n”,
cayman.engine.hours_smoh 2 0x60110c 0x8c
cayman.vehicle_id.vin 17 0x60110e 0x8e
MEM_OFFSET(cayman,cayman.engine.horsepower) );
printf( “cayman.engine.hours_smoh %3lu %p 0x%02lx\n”,
sizeof(cayman.engine.hours_smoh), &cayman.engine.hours_smoh,
), &cayman.e
cayman.vehicle_id.tail_number 8 0x60110e 0x8e
MEM_OFFSET(cayman,cayman.engine.hours_smoh) );
printf( “cayman.vehicle_id.tail_number %3lu %p 0x%02lx\n”, sizeof(cayman.vehicle_id.tail_number), &cayman.vehicle_id.tail_number, MEM_OFFSET(cayman,cayman.vehicle_id.tail_number) );
printf( “cayman.vehicle_id.hull_id %3lu %p 0x%02lx\n”, sizeof(cayman.vehicle_id.hull_id), &cayman.vehicle_id.hull_id, MEM_OFFSET(cayman,cayman.vehicle_id.hull_id) );
sizeof(cayman.vehicle_id.vin), &cayman.vehicle_id.vin, MEM_OFFSET(cayman,cayman.vehicle_id.vin) );
CMPSC 311 – Introduction to Systems Programming
Lets take a closer look
• Lets add up the sizes of the variables
• 128+4+4+1+2+2+max(17,8,12) = 158, not 160! • What happened?
cayman.name
cayman.milage
cayman.type
cayman.engine.cylinders
cayman.engine.horsepower
cayman.engine.hours_smoh
cayman.vehicle_id.vin cayman.vehicle_id.tail_number 8 0x60110e 0x8e cayman.vehicle_id.hull_id 12 0x60110e 0x8e
SZ Addr Off
160 0x601080 0x00
128 0x601080 0x00
4 0x601100 0x80 4 0x601104 0x84 1 0x601108 0x88 2 0x60110a 0x8a 2 0x60110c 0x8c
17 0x60110e 0x8e
CMPSC 311 – Introduction to Systems Programming
The conundrum …
• OK, lets do
程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com