PL1 Lecture 03

You might also like

Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 58

CS112 – Level 1

Programming Languages 1

Lecture 3
Global Variables [ Scope ], Structures, Enumerated Types,
Type Definitions, .. & .. Arrays of Characters [ C Strings ]

Course & Lectures are based on their counterparts in the following courses:
o Harvard University's CS50; An introduction to the intellectual enterprises of
computer science and the art of programming, Harvard School of
Engineering and Applied Sciences.
o UNSW's CS1: Higher Computing, by Richard Buckland – The University of
New South Wales.
o MIT's 6.087 Practical Programming in C (2010), 6.096 Introduction to C++
(2011), and 6.S096 Introduction to C and C++ (2013), MIT (Massachusetts
1
Institute of Technology) OpenCourseWare.
• A basic introduction to C Strings [Arrays
of Characters]
• Strings in C
• String Handling Functions
• Variables’ Scope
O • Global Variables
• User-Defined
u Data Types
t • Data Types

Outline l
i • The typedef Statement
n • Enumerated Data Type
e • Default enum Values
• Structures
• The Concept
• Examples
• A Database Program
.. a basic introduction
to [ C Strings ]
Arrays of Characters

3
Recap
Data Types in C/C++ ..
bool - a Boolean expression of either true or
false

char - a single character like ‘a’, ‘?’, or ‘2’

float - a real number with a decimal value/point

double - a floating-point value with even more


digits

int - integers up to a certain size, or number


of bits, & their negatives

long - integers with more bits, so they can


count higher

STRING - A(N) STRING/ARRAY OF CHARACTERS


Strings

String literals such as “Hello, world!” are actually represented


by C/C++ as a sequence of characters in memory. In other
words, a string is simply a character array and can be
manipulated as such.
Recap

char c1 = 'H';
char c2 = 'I';
char c3 = '!';
Recap

H I !
c1 c2 c3
Recap

72 73 33
c1 c2 c3
Recap

01001000 01001001 00100001


c1 c2 c3
char c[] = "Hi!";
H I ! \0
c[0] c[1] c[2] c[3]
72 73 33 0
c[0] c[1] c[2] c[3]
Strings
Consider the following program:
#include <stdio.h>
int main()
{
char helloworld[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l',
'd', '!', '\0' };
printf("%s", helloworld);
return 0;
}

This program prints Hello, world! Note that the character


array helloworld ends with a special character known as the
null character. This character is used to indicate the end of
the string.
Strings
Character arrays can also be initialized using string literals. In
this case, no null character is needed, as the compiler will
automatically insert one:
● char helloworld[] = "Hello, world!";
bool 1 byte
char 1 byte
int 4 bytes
float 4 bytes
long 8 bytes
double 8 bytes
string ? bytes
...
String Handling Functions
o C language supports a large number of string handling
functions that can be used to carry out many of the string
manipulations.
o These functions are packaged in the string.h library. Hence,
you must include string.h header file in your programs to
use these functions.

The following are the most commonly used string


handling functions:
Method Description
strcat() It is used to concatenate (combine) two strings.
strlen() It is used to show the length of a string.
strrev() It is used to show the reverse of a string.
strcpy() Copies one string into another.
strcmp() It is used to compare two strings.
Variables’ Scope
Global Variables

17
Scope: Global Variables

How many times is function foo() called?


Use a global variable to determine this.
– Can be accessed from any function

i n t numCalls = 0; Global Variable

void f oo ( ) {
++numCalls;
}

i n t main() {
foo(); foo(); foo();
printf("%d", numCalls); / / 3
}
int numCalls = 0;
Scope:
Global i n t r a i s e To P o w e r ( int b a s e , i n t e x p o n e n t )
{
Variables numCalls = numCalls + 1;
int result = 1;
Scope: where a for ( int i = 0; i < exponent; i++ )
variable was declared, {
determines where it result = result * base;
can be accessed from .. }
r e tu r n r e s u l t ;
}

i n t m a x ( int n u m 1 , i n t n u m 2 )
{
numCalls = numCalls + 1;
int result;
if ( num1 > num2 ) { result = num1; }
e ls e { r e s u l t = n u m 2 ; }
r e t ur n r e s u l t ;
}
int numCalls = 0;
Scope:
Global i n t r a i s e To P o w e r ( int b a s e , i n t e x p o n e n t )
{
Variables numCalls = numCalls + 1;
int result = 1;
Scope: where a for ( int i = 0; i < exponent; i++ )
variable was declared, {
determines where it result = result * base;
can be accessed from .. }
• numCalls has global r e tu r n r e s u l t ;
scope – can be }
accessed from any
function i n t m a x ( int n u m 1 , i n t n u m 2 )
{
numCalls = numCalls + 1;
int result;
if ( num1 > num2 ) { result = num1; }
e ls e { r e s u l t = n u m 2 ; }
r e t ur n r e s u l t ;
}
int numCalls = 0;
Scope:
Global i n t r a i s e To P o w e r ( int b a s e , i n t e x p o n e n t )
{
Variables numCalls = numCalls + 1;
int result = 1;
Scope: where a for ( int i = 0; i < exponent; i++ )
variable was declared, {
determines where it result = result * base;
can be accessed from .. }
• numCalls has global r e tu r n r e s u l t ;
scope – can be }
accessed from any
function i n t m a x ( int n u m 1 , i n t n u m 2 )
• result has a function {
scope – each numCalls = numCalls + 1;
int result;
function can have its
if ( num1 > num2 ) { result = num1; }
own separate
e ls e { r e s u l t = n u m 2 ; }
variable named
r e t ur n r e s u l t ;
result }
int numCalls = 0;
i n t r a i s e To P o w e r ( int b a s e , i n t e x p o n e n t ) Scope
{
numCalls = numCalls + 1;
int result = 1;
for ( int i = 0; i < exponent; i++ )
{
result = result * base;
}
return r e s u l t ;
}
i n t m a x ( int n u m 1 , i n t n u m 2 )
{ Global Scope
numCalls = numCalls + 1;
int result; int
if ( num1 > num2 ) { result = num1; } numCalls
else { result = num2; }
return r e s u l t ;
}
raiseToPower function scope max function scope

int int int int


base int result num1 int result
exponent num2
int numCalls = 0;
i n t r a i s e To P o w e r ( int b a s e , i n t e x p o n e n t ) Scope
{
numCalls = numCalls + 1; At A, variables marked in
int result = 1; red are in scope ..
for ( int i = 0; i < exponent; i++ )
{
result = result * base;
} //A
return r e s u l t ;
}
i n t m a x ( int n u m 1 , i n t n u m 2 )
{ Global Scope
numCalls = numCalls + 1;
int result; int
if ( num1 > num2 ) { result = num1; } numCalls
else { result = num2; }
return r e s u l t ;
}
raiseToPower function scope max function scope

int int int int


base int result A num1 int result
exponent num2
int numCalls = 0;
i n t r a i s e To P o w e r ( int b a s e , i n t e x p o n e n t ) Scope
{
numCalls = numCalls + 1; At B, variables marked in
int result = 1; red are in scope ..
for ( int i = 0; i < exponent; i++ )
{
result = result * base;
} //A
return r e s u l t ;
}
i n t m a x ( int n u m 1 , i n t n u m 2 )
{ Global Scope
numCalls = numCalls + 1;
int result; int
if ( num1 > num2 ) { result = num1; } numCalls
else { result = num2; } / / B
return r e s u l t ;
}
raiseToPower function scope max function scope

int int int int


base int result num1 int result B
exponent num2
double squareRoot( double num ) { Loops and if / else statements also have their
double low = 1.0; own scopes. That is, Loop counters are in the
double high = num; same scope as the body of the for loop.
for ( int i = 0; i < 30; i = i + 1)
{
squareRoot function scope
double estimate = (high + low) / 2;
if ( estimate * estimate > num ) { double double
double newHigh = estimate; num double high
high = newHigh; low
}
else {
double newLow = estimate; for loop scope
low = newLow; double
} int i estimate
}
return ( high + low ) / 2;
}
If statement scope else statement scope

double double
newHigh newLow
Scope
double squareRoot( double num ) { Cannot access variables that are out of scope.
double low = 1.0;
double high = num;
for ( int i = 0; i < 30; i = i + 1)
{
squareRoot function scope
double estimate = (high + low) / 2;
if ( estimate * estimate > num ) { double double
double newHigh = estimate; num double high
high = newHigh; low A
}
else {
double newLow = estimate; for loop scope
low = newLow; double
} int i estimate
} // A
return estimate; // ERROR
}
If statement scope else statement scope

double double
newHigh newLow
Scope
double squareRoot( double num ) { Cannot access variables that are out of scope.
double low = 1.0; Solution 1: move the code.
double high = num;
for ( int i = 0; i < 30; i = i + 1)
{
squareRoot function scope
double estimate = (high + low) / 2;
if ( estimate * estimate > num ) { double double
double newHigh = estimate; num double high
high = newHigh; low A
}
else {
double newLow = estimate; for loop scope
low = newLow; double
} int i estimate
B
if ( i == 29 ) {
return estimate; // B
}
} // A If statement scope else statement scope
} double double
newHigh newLow
Scope
double squareRoot( double num ) { Cannot access variables that are out of scope.
double low = 1.0; Solution 2: declare the variable in a higher
double high = num; scope.
double estimate;
for ( int i = 0; i < 30; i = i + 1)
squareRoot function scope
{
estimate = (high + low) / 2; double double
if ( estimate * estimate > num ) { num double high
double newHigh = estimate; low A
high = newHigh;
}
else { for loop scope
double newLow = estimate; double
low = newLow; int i estimate
}
} // A
return estimate;
} If statement scope else statement scope

double double
newHigh newLow
Scope
User-Defined
Data Types
.. Structures,
Enumerated Types, ..
& .. Type Definitions
29
Data Types

Types of data types:

1. Basic / Primary data types:


int, double, float, char, … etc.
2. Aggregate data types:
Array, Structure
3. Custom data types:
Enumeration
Type Definitions
The typedef Statement
• C provides a capability that enables you to assign an alternate name to
a data type. This is done with a statement known as typedef.

typedef type_description type_name;

• The statement: … typedef int Counter; … defines the name Counter


to be equivalent to the C data type int. Variables can subsequently be
declared to be of type Counter, as in the following statement: …
Counter j, n; … the C compiler actually treats the declaration of the
variables j and n, shown in the preceding code, as normal integer
variables.

• The main advantage of the use of the typedef in this case is in


the added readability that it lends to the definition of the
variables.
• the typedef statement does not actually define a new type—only a
The typedef Statement

• In forming a typedef definition, proceed as though a normal variable


declaration is being made. Then, place the new type name where the
variable name would normally appear. Finally, in front of everything,
place the keyword typedef:
• typedef char Linebuf [81];

… defines a type called Linebuf, which is an array of 81


characters.
• Subsequently declaring variables to be of type Linebuf, as in
• Linebuf text, inputLine;
Enumeration
Enumerated Data Type

o An enumerated type is a user defined data type.

o It is defined by giving a name for the type and then giving a


list of labels, which are the only values that a variable of
that type is allowed to have.
Enumerated Data Type

o Enumerated types allow the creation of specialized types


that support the use of meaningful labels within a program.
o They promote code readability with very little overhead in
memory or runtime cost.
Example: You can define a data type for a year’s seasons. So, if
you define a variable period of type season, it can have any
value of the seasons’ labels which were listed.
enum Season { WINTER, SPRING, SUMMER, FALL };
enum Season Period;
Period = WINTER;
Enumerated Data Type .. Example 1
// This program shows how enumeration can be used to
enhance the readability of the code.
#include <stdio.h>
int main(){
enum Month {JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG,
SEP, OCT, NOV, DEC};
enum Season {WINTER, SPRING, SUMMER, FALL};
enum Hemisphere {NORTH, SOUTH, EAST, WEST};

enum Month Mon;


enum Season Period;
enum Hemisphere Region;

. . .

if (Mon == JAN && Region == NORTH)


Period = WINTER;
}
Default enum Values

o If numeric values are not specified, identifiers are assigned


consecutive values starting with 0:
o enum Direction { NORTH = 0, SOUTH = 1, EAST = 2, WEST = 3 };
… … … is equivalent to … … …
o enum Direction { NORTH, SOUTH, EAST, WEST };

o Unless specified, the value assigned to an enumeration constant is


1 more than the value of the previous constant:
o enum MyEnum { ONE = 17, TWO, THREE, FOUR = -3, FIVE };
… … … results in these values … … …
o ONE = 17, TWO = 18, THREE = 19, FOUR = -3, FIVE = -2
Enumerated Data Type .. Example 2
// Program to print the number of days in a month
#include <stdio.h>
int main (void)
{
enum month { january = 1, february, march, april, may, june, july, august,
september, october, november, december };
enum month aMonth;
int days;
printf ("Enter month number: ");
scanf ("%d", &aMonth);
Enumerated Data Type .. Example 2
switch ( aMonth )
{
case january: case march: case may: case july: case august: case october:
case december: days = 31; break;
case april: case june: case september: case november: days = 30; break;
case february: days = 28; break;
default: printf ("bad month number\n"); days = 0;
}
if ( days != 0 ) printf ("Number of days is %d\n", days);
if ( aMonth == february ) printf ("...or 29 if it's a leap year\n");
return 0;
}
Enumerated Data Type .. Key Points

• You can use the enumerated type to declare symbolic names


to represent integer constants.
• By using the enum keyword, you can create a new "type"
and specify the values it may have.
• enum constants are type int; therefore, they can be used
wherever you would use an int.
• The purpose of enumerated types is to enhance the
readability of a program.
• enum primaryColor { red, yellow, blue };
• enum primaryColor myColour, gregsColour;
• myColour = red;
• if ( gregsColour == yellow ) …
Enumerated Data Type .. Key Points

• The C compiler treats enumeration identifiers as integer constants.


Beginning with the first name in the list, the compiler assigns
sequential integer values to these names, starting with 0.
• If you want to have a specific integer value associated with an
enumeration identifier, the integer can be assigned to the identifier when
the data type is defined. Enumeration identifiers that subsequently
appear in the list are assigned sequentially integer values beginning with
the specified integer value plus 1. For example, in the definition:
enum direction { up, down, left = 10, right };
… an enumerated data type direction is defined with the values up,
down, left, and right. The compiler assigns the value 0 to up because
it appears first in the list; 1 to down because it appears next; 10 to left
because it is explicitly assigned this value; and 11 to right because it
appears immediately after left in the list.
Structures
Structures

o An array is a homogeneous datatype since it can contain


only data of the same type, for example:
int array[ 4 ] = { 0, 1, 2, 3 };
o A Struct is a heterogeneous datatype since it can be
composed of data from different types.

Definition:
A Structure is a collection of related data items, possibly of
different types.
Structures .. the Concept

• Structure: a tool for grouping heterogeneous elements


together.
• Array: a tool for grouping homogenous elements together
• Example: Storing Calendar Dates (day, month, year)
• Without using Structures: using independent variables:
• int month = 9, day = 25, year = 2004;
• Using this method, you must keep track of three separate
variables for each date that you use in the program —
even though these variables that are logically related. It
would be much better if you could somehow group these
sets of three variables together. This is what the structure
in C allows you to do!
Structures .. an Example
Defines type struct date, with 3 fields of type int
struct date The names of the fields are local in the context of
{ the structure.
int A struct declaration defines a type: if not
month; followed by a list of variables it reserves no
int day; storage; it merely describes a template or shape
int year; of a structure.
};

Defines variables of
struct date today, purchaseDate; type struct date.

Accesses fields of a variable of type struct date.


today.year = 2004;
A member of a particular structure is referred
today.month = 10;
to
today.day = 5;
in an expression by a construction of
the form structurename.member.
Structures .. Example 1
o Structures hold data that belong together.
o For example, a Student’s information may contain the Student ID,
Age, Gender, and GPA …
Defining a structure for the student’s info
struct StudentInfo
{
int Id; The “StudentInfo” structure has 4
int age;
char gender; members of different data types.
double gpa;
};
Defining a variable of the type StudentInfo
struct StudentInfo Student1, Student2;
Assigning values to the structure’s members
Student1.Id = 12345; Student1.age = 17;
Student1.gender = 'M'; Student1.gpa = 3.5;
Structures .. Example 2
o Structures hold data that belong together.
o E.g., Bank account: account number, name, currency, balance, …
Defining a structure for bank accounts
struct BankAccount
{ The “BankAcount” structure includes
(1) simple, (2) array, & (3) structure
char Name[15];
data-types as members.
int AccountNo;
double Balance;
struct date Birthday;
};
Defining a variable of the type BankAccnout
struct BankAccount account1, account2;
Structures .. Example 2
Assign a values for the structure members
account1.Name[0] = 'A';
account1.Name[1] = 'h';
account1.Name[2] = 'm';
account1.Name[3] = 'e';
account1.Name[4] = 'd';
account1.Name[5] = '\0';
account1.AccountNo = 12345;
account1.Balance = 3442.3;
account1.Birthday.day = 1;
account1.Birthday.month = 11;
account1.Birthday.year = 2000;
Structures .. Example 3
/* A program that demonstrates how to define a structure and how to
use it in the main function. */
#include <stdio.h>
struct employment {
int id_number;
int age;
float salary;
};
int main() {
struct employment employee;
/* This is now an employee variable that has modifiable variables
inside it. */
employee.age = 22;
employee.id_number = 1;
employee.salary = 12000.21;
}
Structures .. Example 4: Determine Tomorrow’s Date
// Program to determine tomorrow's date
#include <stdio.h>
int main (void)
{
struct date
{
int day;
int month;
int year;
};
struct date today, tomorrow;
const int daysPerMonth[ 12 ] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
printf ("Enter today's date (dd mm yyyy): ");
scanf("%d%d%d", &today.day, &today.month, &today.year);
Structures .. Example 4: Determine Tomorrow’s Date
if( today.day != daysPerMonth[ today.month - 1] ) { // last day in month ..
tomorrow.day = today.day + 1;
tomorrow.month = today.month;
tomorrow.year = today.year;
}
else if ( today.month == 12 ) { // end of year ..
tomorrow.day = 1;
tomorrow.month = 1;
tomorrow.year = today.year + 1;
}
else { // end of month ..
tomorrow.day = 1;
tomorrow.month = today.month + 1;
tomorrow.year = today.year;
}
printf ("Tomorrow's date is %d/%d/%d.\n", tomorrow.day, tomorrow.month,
tomorrow.year );
return 0; }
Initializing Structures ..
struct date
{
int day;
int month;
int year;
};

struct date today = {7, 2, 2005 };

struct date today;


today = (struct date) { 9, 25, 2004};

struct date today;


today = (struct date) { .month = 9, .day = 25, .year =
2004 };
Structures Example 5 .. A Database Program
/* A program that accepts and saves from the user a set of employees, saving
them in an array. This array represents a database of 10 employees. The program
has a function that calculates the average of the salaries entered by the user. */
#include <stdio.h>
struct employment{ int id_number; int age; float salary; };
float getAverageSalary( struct employment[], int);
int main() {
const int length = 10;
struct employment employee[ length ];
printf("Enter the employees:\n");
for( int i = 0; i < length; i++ ) {
printf("Enter the employee number %d:\n", i + 1);
printf("Enter the id: \n"); scanf("%d", &employee[i].id_number);
printf("Enter the age: \n"); scanf("%d", &employee[i].age);
printf("Enter the salary: \n"); scanf("%f", &employee[i].salary);
}
printf("The average salary is: %f", getAverageSalary( employee, length ));
return 0;
}
Structures Example 5 .. A Database Program
float getAverageSalary( struct employment e[], int length )
{
float avg = 0.0;
for( int i = 0; i < length; i++ )
{
avg += e[i].salary;
}
avg /= length;
return avg;
}
Structures Example 5 .. A Database Program
// In the previous program, write a function that prints the salary of a given
employee Id.

void printSalary( struct employment e[], int id)


{
for( int i = 0; i < 10; i++ )
{
if( e[i].id_number == id )
printf("The salary of the employee (%d) = %f", id, e[i].salary );
}
}
Structures Example 5 .. A Database Program
Take-home Assignment

In the previous program, answer the following:


o What is the size of the array (database) in the memory?
o Write down the code required (a function) to calculate and print
the sum of the salaries of all the employees in the database.
o Write down the code required (a function) to print the database as
a table.
Thanks! .. Questions?

You might also like