C_Programming_2 (1)
C_Programming_2 (1)
Objectives
At the end of this self-learning lab, you should be able to:
Know how to use variables, flow of control and array in a C program.
Know how to use function (pass by value / pass by reference) in a C
program.
Know some simple C-string functions for manipulating char arrays.
Variable - Both C and C++ support the same data types like int, double and char.
Flow of control - The syntax for control statements are the same. That is, if-else
statements, for-loops and while-loops are defined identically.
Note that we define the variable int i in the for loop initialization part, which is a
valid syntax in C++.
Unfortunately, it is not a valid syntax if we use gcc to compile variable.c. It is
because gcc by default is not using the c99 standard.
1
$ gcc variable.c –o variable
Error 'for' loop initial declaration used outside C99 mode
...
From C99 onwards (and C++) the standard also allows variables to be declared inside
for loops
We need to add the flag -std=c99 to ask the gcc compiler to use the c99 standard.
$ gcc –std=c99 variable.c –o variable
(No error messages, compile success)
$ ./variable
45
Function - The syntax for functions (pass by value, or called pass by copy) is the same
as the syntax in C++.
Consider the file function1.c
$ vi function1.c
Code explanations:
In this example we define a function called sum() with two input parameters double a
and double b.
o Note that both input parameters are pass by value, or we call it pass by copy.
o It is okay in this case because the sum() function does not update the variables a
and b in the main() function, it just returns the sum, which is a double value .
o Note that when sum() is called, the value of a and b are copied to input parameters
a and b in sum(), i.e., sum() works on a copy of the values.
We use the %g conversion specifier in the printf() function to output the double
value without trailing zeros on screen.
2
Let’s try to compile the program and run it.
$ gcc function1.c –o function1
$ ./function1
The sum is 26.5
The sum is 10
As a revision, let’s look at the two approaches for pass by reference in C++:
Consider the file function2.cpp. There are three swap functions.
$ vi function2.cpp
Pass by value swap1(double a, double b)
void swap1(double a, double b){
double temp = a;
a=b;
b=temp;
}
o Note that the swap1() function failed to swap the values of the variables a and
b in the main() function because they are pass by value (or called pass by
copy).
o In swap1() it is just swapping a copy of the value of the variables a and b in
the main() function, therefore swap1() cannot swap the variables that we
pass in.
Pass by reference method 1 - void swap2(double & a, double & b)
void swap2(double & a, double & b){
double temp = a;
a=b;
b=temp;
}
o Note that this swap2() function can swap the values of the variables a and b in
the main() function because they are pass by reference.
3
o However, this way of passing by reference is supported in C++ only! C doesn’t
support this method to specify the pass by reference
4
Let’s consider function2.c as an illustration.
$ vi function2.c
Let’s try to fix function2.c by commenting out the definition and function call of
swap2().
$ gcc function2.c –o function2
$ ./function2
a = 5.5, b = 10.5
a = 5.5, b = 10.5
a = 10.5, b = 5.5
5
Checkpoint 10.2a (Please submit your answer to Moodle.)
Let’s write a function that computes the sine and cosine values of a user input degree
value.
Consider the file sincos.c
$ vi sincos.c
sincos.c contains the following unfinished code
#include <stdio.h>
#define PI 3.14159265
int main(){
double dSin;
double dCos;
int degree;
return 0;
}
6
The first parameter - a simple int variable for the degree, let’s call it d in the
function. And we pass this variable by value.
The second parameter - a double variable for storing the sine value of d, let’s
call it dSin, we need to pass this variable by reference.
The third parameter - a double variable for storing the cosine value of d, let’s
call it dCos, we need to pass this variable by reference.
o We need to include the <math.h> library to use the buildin sine and cosine
functions (sin() and cos())
#include <math.h> // for sin() and cos()
o With the <math.h> library, we can use the sin() and cos() function. However,
both functions accept radian (But not degree) as their input. Given the degree in
variable d, the following function call return the sine value of d.
??? = sin(d*PI/180);
Note that d*PI/180 changes the degree value in d into the corresponding
radian value.
You need to assign the computed sin value to dSin, note that dSin is pass by
reference and it should be a pointer to double in the GetSinCos() function.
Therefore we need to dereference the pointer dSin to access the double value.
o The following function call return the cosine value of d.
??? = cos(d*PI/180);
You need to assign the computed cosin value to dCos, note that dCos is pass by
reference and it should be a pointer to double in the GetSinCos() function.
Task 3. Call the GetSinCos() function.
o The first parameter is pass by value, we need to provide degree as the first
parameter.
o The 2nd and 3rd parameters are pass by reference, we need to provide the addresses of
dSin and dCos to the function.
Let’s try to compile the program and run it. Note that we have to add the flag –lm to link
the executable with the math library (even if we have included math.h header)
$ gcc sincos.c –o sincos -lm
$ ./sincos
30
The sin is 0.5
The cos is 0.866025
7
Section 4. Array
Code explanations:
Define a function
salary_increase() with an
integer array as input parameter.
Same as C++, passing an array into
function behaves like pass by
reference. i.e., If you change the
value of the array inside the function,
the input array in the function caller
also changes.
o In this case, the int array
salary in the main()
function is updated after calling
salary_increase().
8
The relationship between array and pointer
Code explanations:
Input parameter int *sal is equivalent to int sal[]. (Same as C++)
o It is because when we pass an array into a function, it is actually the address
of the 1st slot of the array that is passed in.
o This also explains why passing an array into a function behaves like pass by
reference; it is because the array is NOT copied to the workspace of the
function. Instead it is the pointer to the first slot of the array that is passed
into the function.
(*sal)
o We use the “*” operator to dereference the pointer variable sal.
o Note that sal is an int type pointer variable, which stores the address of a
memory cell that stores an integer value.
o (*sal) means that we are refereeing to the memory cell with the address
equal to the address stored in sal (but not just the address value stored in
sal).
sal++
o We can use the increment / decrement operator on pointer variable to go to
the next / previous slot of the array.
Let’s try to replace the salary_increase() function in array1.c by the
above function and recompile the code, you will notice that the two functions are
equivalent to each other.
9
Section 5. C-String
Note that the null character is inserted by the compiler automatically in position 11.
The characters stored in position 12 to 14 are not part of the string and ignored during
string operations like copying (strcpy()) and comparison (strcmp()).
Assume we want to change the string to “Hello world!” we can do it as follows.
10
Function Effect
Copy char array s2 to s1.
strcpy (char s1[], char s2[])
s2 is not changed.
Append s2 after the end of s1.
Note that the first character of s2 will
strcat (char s1[], char s2[])
overwrite the null character of s1.
s2 is not changed.
Return negative if s1<s2,
strcmp (char s1[], char s2[]) return 0 if s1==s2,
return positive if s1>s2.
Return the length of the string stored in the
strlen (char s1[])
char array s1.
11
Consider the file string1.c as an illustration.
$ vi string1.c
Code explanations:
We need to include <string.h> header file to use the string functions.
Create two char arrays a and b, both store the string value “Kit”.
Use strcmp() to compare if two strings are the same. Note that the function returns 0 if
the two strings are identical.
Use strcpy() to copy a string value into a char array.
o In this case we assign “David” into the content of char array b. (However there are
some problems in this line of code, to be explained shortly.)
Use strcat() to concatenate two strings, the content of a and b are concatenated and
the result is stored in the first parameter (i.e., the char array a.)
Let’s try to compile the program and run it. There could be (not always) some run-time
problem in the code. Can you identify the problem?
$ gcc string1.c –o string1
$ ./string1
a b are the same
The value of b is David.
a: KitDavid, b: David.
12
When using strcpy() or strcat(), the programmer needs to ensure that the first
input parameter has enough space to hold the final content.
Otherwise, a runtime error may occur due to array access out of bound.
What we need to do is to provide the initial size of the char arrays a and b to be
large enough, say, 100 char slots.
o Then strcpy(b, "David") will have enough space to store “David” (at
least 6 chars) in b.
o Then strcat(a,b) will have enough space to store “KitDavid” (at least
9 chars) in a.
13
Checkpoint 10.2b (Please submit your answer to Moodle.)
Write a program that reads in a string input by users, and changes all the characters
from Upper cases to Lower cases.
Consider the file string2.c
$ vi string2.c
string2.c contains the following unfinished code
#include<stdio.h>
#include<string.h>
int main(){
char input[100];
// Task 1. Read in user input to the char array input.
printf("%s",input);
}
14
Task2. Build the toLower() function.
o The logic is to use a for loop to scan through the char array. What is the string
function to get the length of the char array? (Hints: look at the last row in the table in
page 11.)
for (int i = 0 ; i< ??? ; i++){
// Check individual char a[i] here ...
}
o The logic of comparing whether a character a[i] is a capital letter is
if(a[i] >= 'A' && a[i]<='Z'){
// Update a[i] to lower case
}
o Changing the letter from Upper case to Lower case is left as your own exercise.
Reminder: From level 1 programming course we learn that a[i]+'a'-'A'
will change the letter from Upper case to Lower case, do you still remember it?
a[i] = a[i] + 'a' – 'A'
References
The C string library <string.h>
http://www.cplusplus.com/reference/cstring/
C Tutorial – Strings and Text Handling
http://cplus.about.com/od/learningc/ss/strings.htm
Cprogramming.com – Lesson 9 : C-string
http://www.cprogramming.com/tutorial/c/lesson9.html
15