You are on page 1of 57

BITS Pilani

K K Birla Goa Campus

CSF111: Computer Programming

Miscellaneous topics

Swaroop Joshi

2023
Scope of a Variable

✤ Area of the code where the variable is valid, i.e., where it can be accessed

✤ From the place where it is declared to the end of the enclosing block

✤ Area of the code within the immediately enclosing pair of braces {…} is
called a block
Parameter passing

✤ When you de ne a function, the parameter list is called formal parameters

✤ When you call a function, the parameters you pass are called actual
parameters or arguments

✤ The expressions that represent the arguments are evaluated and the values
are copied into the variables representing the formal parameters

✤ When a function returns with a value, that value is again copied into the
calling code
fi
Example
int area_rectangle(int length, int width) {
length++;
return (length-1) * width;
}

int main() {
int length = 4;
int width = 6;

printf("Length: %d, Width: %d, ", length, width);


printf("Area: %d\n", area_rectangle(length, width));

return 0;
}
Remember the basics:
Example A variable declaration means “give me a box
big enough to hold a value of the given type
and let me call it by the given name”
int area_rectangle(int length, int width) {
length++;
return (length-1) * width;
}

int main() {
int length = 4;
int width = 6;

printf("Length: %d, Width: %d, ", length, width);


printf("Area: %d\n", area_rectangle(length, width));

return 0;
}
Example
int area_rectangle(int length, int width) {
length++;
return (length-1) * width;
}

int main() {
int length = 4;
int width = 6;

printf("Length: %d, Width: %d, ", length, width);


These declarations
printf("Area: %d\n", area_rectangle(length, width)); of length and width creates
two boxes with the names length and width big
enough to hold integers; the compiler makes a
return 0; note that these are from the function main
}
Example 4
length (main)
6
width (main)

int area_rectangle(int length, int width) {


length++;
return (length-1) * width;
}

int main() {
int length = 4;
int width = 6;

printf("Length: %d, Width: %d, ", length, width);


These declarations
printf("Area: %d\n", area_rectangle(length, width)); of length and width creates
two boxes with the names length and width big
enough to hold integers; the compiler makes a
return 0; note that these are from the function main
}
Example 4
length (main)
6
width (main)

int area_rectangle(int length, int width) {


length++;
return (length-1) * width;
} These declarations creates two new boxes with
the names length and width big enough to hold
int main() { integers; the compiler makes a note that these
int length = 4; are from the function area_rectangle
int width = 6;

printf("Length: %d, Width: %d, ", length, width);


printf("Area: %d\n", area_rectangle(length, width));

return 0;
}
Example 4
length (main)
6
width (main)
4 6
length (area_rectangle) width (area_rectangle)

int area_rectangle(int length, int width) {


length++;
return (length-1) * width;
} These declarations creates two new boxes with
the names length and width big enough to hold
int main() { integers; the compiler makes a note that these
int length = 4; are from the function area_rectangle
int width = 6;

printf("Length: %d, Width: %d, ", length, width);


printf("Area: %d\n", area_rectangle(length, width));

return 0;
}
Example 4
length (main)
6
width (main)
4 6
length (area_rectangle) width (area_rectangle)

int area_rectangle(int length, int width) {


length++;
return (length-1) * width;
}

int main() {
int length = 4;
int width = 6;

printf("Length: %d, Width: %d, ", length, width);


printf("Area: %d\n", area_rectangle(length, width));

return 0;
}
Example 4
length (main)
6
width (main)
4 6
length (area_rectangle) width (area_rectangle)

int area_rectangle(int length, int width) {


Changes to length and width in this scope does
length++;
not affect the length and width in the other
return (length-1) * width;
} scope (because they are different variables!)

int main() {
int length = 4;
int width = 6;

printf("Length: %d, Width: %d, ", length, width);


printf("Area: %d\n", area_rectangle(length, width));

return 0;
}
Example 4
length (main)
6
width (main)
54 6
length (area_rectangle) width (area_rectangle)

int area_rectangle(int length, int width) {


length++;
return (length-1) * width;
}
The value of the return
int main() {
expression, 24, is copied back
int length = 4;
int width = 6; into the calling code

printf("Length: %d, Width: %d, ", length, width);


printf("Area: %d\n", area_rectangle(length, width));

return 0;
}
Example 4
length (main)
6
width (main)
54 6
length (area_rectangle) width (area_rectangle)

int area_rectangle(int length, int width) {


length++;
return (length-1) * width;
}

int main() {
int length = 4; The return value 24 ‘replaces’ the
int width = 6; function call, thus it prints 24

printf("Length: %d, Width: %d, ", length, width);


printf("Area: %d\n", area_rectangle(length, width));

return 0;
}
Example 4
length (main)
6
width (main)
54 6
length (area_rectangle) width (area_rectangle)

int area_rectangle(int length, int width) {


length++;
return (length-1) * width;
}

int main() {
int length = 4;
int width = 6;

printf("Length: %d, Width: %d, ", length, width);


printf("Area: %d\n", area_rectangle(length, width));
printf("Length after the call: %d\n", length);
return 0;
} What is the value of length here?
Scopes in the same function
Scopes in the same function

✤ The concept of multiple scopes applies not only to different functions, but
within the same function too
Scopes in the same function

✤ The concept of multiple scopes applies not only to different functions, but
within the same function too

✤ Remember: each pair of curly braces creates a new scope!


Scopes in the same function

✤ The concept of multiple scopes applies not only to different functions, but
within the same function too

✤ Remember: each pair of curly braces creates a new scope!

✤ In other words

✤ Scope of a variable is the immediate enclosing pair of curly braces

✤ It does not exist outside that


What is the output of this piece of code?

int x = 0;
printf("Enter an integer: ");
scanf("%d", &x);

if (x > 0) {
int y = 0;
printf("Enter an integer greater than the previous one: ");
scanf("%d", &y);
if (y > x) {
printf("Good choice!\n");
} else {
printf("Ugh! Can't you follow simple instructions!\n");
}
}
printf("You entered %d and %d\n", x, y);
What is the output of this piece of code?

int x = 0;
printf("Enter an integer: ");
scanf("%d", &x);

if (x > 0) {
int y = 0;
printf("Enter an integer greater than the previous one: ");
scanf("%d", &y);
if (y > x) {
printf("Good choice!\n");
Syntax error! y is not available in
} else { this scope!
printf("Ugh! Can't you follow simple instructions!\n");
}
}
printf("You entered %d and %d\n", x, y);
Switch-case
int watts;
printf("Enter wattage for your bulb: ");
scanf("%d", &watts);
int life;
switch (watts)
{
case 25:
life = 2500;
✤ Alternative to if-else chains for break;
case 40:
multiple alternative decisions
case 60:
life = 1000;
✤ The expression after case must be a break;
case 75:
constant → strings not supported
case 100:
life = 750;
✤ Careful with break break;
default:
life = 0;
✤ Use of default }
printf("The bulb should last %d hours\n", life);
char grade

Doesn’t work for ranges marks>90

char grade(int marks) {


char grade; grade='O' marks>80
if (marks > 90) {
grade = 'O';
marks>70
} else if (marks > 80) { grade='E'
grade = 'E';
} else if (marks > 70) {
grade = 'A'; grade='A'
} else {
grade='P'
grade = 'P';
}
return grade;
return grade
}
char grade

Doesn’t work for ranges marks>90

char grade(int marks) { Some compilers, like GCC, can


char grade; grade='O'
handle marks>80
this using the GNU Case
if (marks > 90) { Range Extension; not part of
grade = 'O'; standard C
marks>70
} else if (marks > 80) { grade='E'
grade = 'E';
} else if (marks > 70) {
grade = 'A'; grade='A'
} else {
grade='P'
grade = 'P';
}
return grade;
return grade
}
Overflow

✤ Over ow: the result does not t in the result type

Image courtesy Wikipedia


fl
fi
Overflow

✤ Over ow: the result does not t in the result type

#include<stdio.h>
#include<limits.h>

int main() {
printf("%d to %d\n", INT_MIN, INT_MAX);
printf("%d\n", INT_MAX + 1);

return 0; Image courtesy Wikipedia


}
fl
fi
Do not use double to extend the range of ints

✤ Doubles are meant to represent real numbers (can have precision issues)

✤ Ints are meant to represent integers

✤ Do not use doubles to represent bigger integers!

✤ There are other integer-types to represent bigger integers

✤ Not a part of this course, nd out on your own


fi
Implicit type conversion
Implicit type conversion

✤ When an expression is used in the context where a value of a different type


is expected, conversion may occur
Implicit type conversion

✤ When an expression is used in the context where a value of a different type


is expected, conversion may occur

✤ 1.0 * 42 → 42 converted to a double before evaluation


Implicit type conversion

✤ When an expression is used in the context where a value of a different type


is expected, conversion may occur

✤ 1.0 * 42 → 42 converted to a double before evaluation

✤ 10 * 4.2 → 10 converted to a double before evaluation


Implicit type conversion

✤ When an expression is used in the context where a value of a different type


is expected, conversion may occur

✤ 1.0 * 42 → 42 converted to a double before evaluation

✤ 10 * 4.2 → 10 converted to a double before evaluation

✤ int x = 10 * 4.2; → RHS is converted to an int


Implicit type conversion

✤ When an expression is used in the context where a value of a different type


is expected, conversion may occur

✤ 1.0 * 42 → 42 converted to a double before evaluation

✤ 10 * 4.2 → 10 converted to a double before evaluation

✤ int x = 10 * 4.2; → RHS is converted to an int

✤ int function(…) { … ; return 10 * 4.2; } → return value converted to an int


Implicit type conversion

int x = 10 * 9.7;
printf("x as an int: %d\n", x);
printf("x as a char: %c\n", x);
Implicit type conversion

int x = 10 * 9.7;
printf("x as an int: %d\n", x); x as an int: 97
printf("x as a char: %c\n", x); x as a char: a
Implicit type conversion

int x = 10 * 9.7;
printf("x as an int: %d\n", x); x as an int: 97
printf("x as a char: %c\n", x); x as a char: a

✤ Chars are stored as numbers internally


Implicit type conversion

int x = 10 * 9.7;
printf("x as an int: %d\n", x); x as an int: 97
printf("x as a char: %c\n", x); x as a char: a

✤ Chars are stored as numbers internally

✤ Some common ASCII codes (link)


Implicit type conversion

int x = 10 * 9.7;
printf("x as an int: %d\n", x); x as an int: 97
printf("x as a char: %c\n", x); x as a char: a

✤ Chars are stored as numbers internally

✤ Some common ASCII codes (link)

✤ 32: space, 48–57: digits 0–9, 65–90: letters A–Z, 97–122: letters a–z
Implicit type conversion

int x = 10 * 9.7;
printf("x as an int: %d\n", x); x as an int: 97
printf("x as a char: %c\n", x); x as a char: a

✤ Chars are stored as numbers internally

✤ Some common ASCII codes (link)

✤ 32: space, 48–57: digits 0–9, 65–90: letters A–Z, 97–122: letters a–z

✤ You don’t have to remember these!


Implicit type conversion
Implicit type conversion

✤ Since chars are numbers, you can do arithmetic on them


Implicit type conversion

✤ Since chars are numbers, you can do arithmetic on them

✤ Don’t do it unless you really have to!


Implicit type conversion

✤ Since chars are numbers, you can do arithmetic on them

✤ Don’t do it unless you really have to!

char ch = 'a';
printf("The second letter from '%c' is '%c'\n", ch, ch + 2);
Implicit type conversion

✤ Since chars are numbers, you can do arithmetic on them

✤ Don’t do it unless you really have to!

char ch = 'a';
printf("The second letter from '%c' is '%c'\n", ch, ch + 2);

The second letter from 'a' is 'c'


Contracts
/**
* @brief Returns the non-negative square-root
Contracts * of the given non-negative number.
* Requires n >= 0
*/
double sqrt(double n)
/**
* @brief Returns the non-negative square-root
Contracts * of the given non-negative number.
* Requires n >= 0
*/
double sqrt(double n)
✤ Two-way relation:
/**
* @brief Returns the non-negative square-root
Contracts * of the given non-negative number.
* Requires n >= 0
*/
double sqrt(double n)
✤ Two-way relation:

✤ User of the function must satisfy the Requires clause to get a meaningful
result
/**
* @brief Returns the non-negative square-root
Contracts * of the given non-negative number.
* Requires n >= 0
*/
double sqrt(double n)
✤ Two-way relation:

✤ User of the function must satisfy the Requires clause to get a meaningful
result

✤ Implementer of the function must implement the speci cations assuming


only valid input is given

fi
/**
* @brief Returns the non-negative square-root
Contracts * of the given non-negative number.
* Requires n >= 0
*/
double sqrt(double n)
✤ Two-way relation:

✤ User of the function must satisfy the Requires clause to get a meaningful
result

✤ Implementer of the function must implement the speci cations assuming


only valid input is given

✤ What about the invalid input?

fi
/**
* @brief Returns the non-negative square-root
Contracts * of the given non-negative number.
* Requires n >= 0
*/
double sqrt(double n)
✤ Two-way relation:

✤ User of the function must satisfy the Requires clause to get a meaningful
result

✤ Implementer of the function must implement the speci cations assuming


only valid input is given

✤ What about the invalid input?

✤ The implementer can choose to do anything!

fi
Meaning of contract

✤ What should the function do if the precondition is not satis ed by the caller?

✤ Anything?

✤ Return a default value

✤ Print an error message

✤ Abort the program

✤ Not end the program at all!

✤ …
fi
Meaning of contract

✤ What should the function do if the precondition is not satis ed by the caller?

✤ Anything?
All of these are valid responses
✤ Return a default value Since the user (i.e., the calling code) of the
function did not hold its end of the contract
✤ Print an error message (passing only the valid values), the implementer
(i.e., the function code) is not responsible for
✤ Abort the program
anything speci c
✤ Not end the program at all!

✤ …
fi
fi
Separation of concerns
Separation of concerns

✤ When you are calling a function,

✤ You are only worried about calling it with valid parameters

✤ As long as you do that, you can apply the contract to reason about the
program
Separation of concerns
When calling sqrt, you make sure you pass a
non-negative value
And you are guaranteed to get the expected
✤ When you are calling a function, result

✤ You are only worried about calling it with valid parameters

✤ As long as you do that, you can apply the contract to reason about the
program
Separation of concerns
When calling sqrt, you make sure you pass a
non-negative value
And you are guaranteed to get the expected
✤ When you are calling a function, result

✤ You are only worried about calling it with valid parameters

✤ As long as you do that, you can apply the contract to reason about the
program

✤ When you are implementing a function

✤ You are only worried about handling valid parameters


Separation of concerns

✤ When you are calling a function,

✤ You are only worried about calling it with valid parameters


When implementing sqrt, you don’t care about
✤ As long as you do that, you can apply thenegative
contract to reason
inputs about
and complex the
numbers
program

✤ When you are implementing a function

✤ You are only worried about handling valid parameters

You might also like