Lecture Data Structures and Practise

Download Report

Transcript Lecture Data Structures and Practise

Lecture 10
Introduction to Programming
in C
Prof. Dr. Arne Kutzner
Hanyang University / Seoul Korea
Pointers / Introduction
Variables and Memory Address
• Every variable has some location in the memory that
holds the value of the variable. This location is called
the address of the variable.
1000
num
0
1004
1008
1012
int num = 0;
1016
The address of
the variable num
1020
Introduction to C
L10.3
Pointers
• A pointer is also a variable, but unlike
the other types of variables that we
have seen, it contains a memory
address as its value.
Introduction to C
L10.4
Pointer Declaration
• To declare a pointer variable, a
asterisk(*) should placed in front of
name of the name of the variable.
Example:
int *p;
p is a pointer to an integer value (i.e. p contains the
address of some memory cell that contains an
integer value)
Introduction to C
L10.5
Address Operator
• You can get the memory address of
some variable by using the address
operator &. Example:
int x = 0;
x
0
int *p;
p = &x;
The pointer p gets the
address of the variable x as
its value
Introduction to C
p
1004
1000
1004
1008
1012
1016
1020
L10.6
How to deference pointers?
• For dereferencing a pointer place a
asterisk in front of the pointer variable
name. Example:
int x = 0;
int *p;
x
5
p = &x;
*p = 5;
1004
p
Write the value 5 to the memory
location referenced by p Introduction to C
1000
1004
1008
1012
1016
1020
L10.7
Pointers / More explanation
x 
0
p  1004
*p  num  0
&x  1004
The * operator is referred
to as indirection or
dereferencing operator
• So we say:
p is a pointer to the integer variable x.
p
x
0
*p is equal to 0 (the value of x).
p indirectly references the value 0.
Introduction to C
L10.8
Pointer Types
• Pointers can be declared to point to
variables of any type.
• Examples:
int *p1;
pointer to an integer
double *p2; pointer to a
floating point number
char *p3;
pointer to a character
Introduction to C
L10.9
Example Program 1
int main() {
…
int x1 = 5;
int x2 = 8;
int *x1ptr;
int *x2ptr;
x1ptr = &x1;
x1
5
1000
x2
8
1004
x1ptr
?
1008
x2ptr
?
1012
x1
5
1000
x2
8
1004
x1ptr
1000
1008
x2ptr
1004
1012
x1
5
1000
x2
12
1004
x1ptr
1000
1008
x2ptr
1004
1012
x2ptr = &x2;
*x2ptr = 12;
…
}
Introduction to C
L10.10
Example Program 2
1
2
3
4
#include <stdio.h>
int main() {
int num1, num2, product;
int *ptr_num1, *ptr_num2;
5 num1 = 5;
6 num2 = 7;
7 ptr_num1 = &num1;
8 ptr_num2 = &num2;
9 product = num1 * (*ptr_num2);
…
}
Introduction to C
The resulting
memory picture
num1
5
1000
num2
7
1004
product
35
1008
ptr_num1
1000
1012
ptr_num2
1004
1014
* operator specifies
dereferencing a pointer
* operator specifies
multiplication
L10.11
Description of
Example Program 2
• Line 3: integer variable declaration
• Line 4: pointer to integer declaration
• Line 7: The address of num1 is
evaluated by the & operator and stored
in ptr_num1
• Line 9: The value in num1 is multiplied
by the value of the address location
pointed by ptr_num2
Introduction to C
L10.12
Pointer type equivalence
• A pointer can dereference only a
variable which is of the same type.
Example:
int n = 5;
double x = 5.0;
int *ptr1;
double *ptr2;
ptr1 = &n;
ptr2 = &n;
ptr1 = &x;
Compile error!
ptr1 is a pointer to integer whereas x
is a floating point number.
ptr2 is a pointer to double whereas n
is an integer number.
Introduction to C
L10.13
Warning:
Uninitialized Pointers
• Dereferencing a pointer that has not
been properly initialized
Example:
The pointer contains an arbitrary address,
int *p;
so *p=1 may overwrite some arbitrary
location in memory which can cause severe
problems.
Run-time error!
No compile error!
*p = 1;
printf("Value is %d", *p);
Introduction to C
L10.14
Effects with uninitialized pointers
• Program attempts to access some
random memory location.
Possible effects:
– Fatal Runtime error (common program runtime error message: "segmentation fault").
– Accidentally modifying other data /
variables. Program continues but delivers
incorrect result.
Introduction to C
L10.15
Functions and Pointers
Pointers and Functions
• Function arguments can be of some “pointer type”.
Example:
void main () {
int i;
fun (&i);
printf("%d", i)
}
void fun (int *p) {
*p = 1;
}
Type of function
arguments is “pointer
to int”
Introduction to C
L10.17
Call by Reference
• In the example on the slide before the
statement *p = 1 in fun changes the
value of i defined main in.
• Because p refers i in fun we call this
form of argument passing call by
reference.
Introduction to C
L10.18
Example for the Application of
Call by Reference
• A function fun shall have two input
arguments and two output argument.
x
Input
y
x+y
fun
x*y
Output
(Remember: Using return we can
deliver only one value!)
Introduction to C
L10.19
Application of Call by Reference
The addresses of
sum and product
are passed as
arguments.
int main() {
int x, y, sum, product;
x = 3;
y = 5;
fun (x, y, &sum, &product)
}
void fun (int a, int b, int *p1, int *p2)
{
*p1 = a + b;
*p2 = a * b;
}
Introduction to C
L10.20
Application of Call by Reference
• In the previous example, the
addresses (not values) of the
variables sum and product
are copied to the function
pointer arguments p1 and p2.
In this way, sum and
product have the same
memory locations as *p1 and
*p2, respectively.
Introduction to C
x
3
y
5
p1
product
p2
sum
1476
15
1468
1468
8
1476
….
a
3
b
5
L10.21
Comparison of Call by Reference
and Call by Value
• With the function call by value, the values of the
function arguments can't be modified by the function.
• With the function call by reference, the function
arguments are the addresses, not the values of the
corresponding variables. These addresses are
copied into some pointers which are function
arguments. Therefore, modifying the values stored in
the addresses pointed by these pointers modifies
also the values of the variables.
Introduction to C
L10.22
Comparison of Call by Reference
and Call by Value
What outputs do we get and why?
Call by value
Call by reference
swap(n, m);
printf("%d, %d", n, m);
…
swap(&n, &m);
printf("%d, %d", n, m);
…
void swap(int x, int y)
int temp = x;
x = y;
y = temp;
}
void swap(int *x, int *y)
int temp = *x;
*x = *y;
*y = temp;
}
…
int n = 1;
int m = 2;
…
int n = 1;
int m = 2;
Introduction to C
L10.23
Remark: scanf
• Now you should be able to understand
the scanf function:
scanf("%d", &num);
Memory address of
num
Introduction to C
L10.24
Pointers and Arrays /
Pointer Arithmetic
Pointers and Arrays
• In C there is a strong relationship
between the concepts of pointers and
arrays
• An array name is basically a const
pointer. (A pointer with fixed address)
int *x;
int a[10];
x = a;
This statement is OK!!!
It assigns x the address of the
first elements array a.
Introduction to C
L10.26
Pointers and Arrays (cont.)
• You can even use the [ ] operator with a
pointer:
int *x;
int a[10];
x gets “the address of a[2] ”
x = &a[2];
for (int i = 0;i < 3 ;i++)
x[i] is identical to a[i+2]
x[i]++;
Introduction to C
L10.27
Pointer arithmetic
• Integer math operations can be used with
pointers.
• If you increment a pointer, it will be
increased by the size of whatever it points
to.
int *ptr = a;
*(ptr+2)
*ptr
a[0]
a[1]
a[2]
a[3]
*(ptr+4)
a[4]
int a[5];
Introduction to C
L10.28
printing an array
void print_array(int a[], int len) {
for (int i = 0;i < len; i++)
printf ("[%d] = %d", i, a[i]);
}
void print_array(int *a, int len) {
for (int i = 0;i < len; i++)
printf ("[%d] = %d", i, *a++);
}
Introduction to C
L10.29
Arrays of Pointers
• Like for any other type you can create
arrays of pointers:
int a[] = {0, 1, 2};
int b[] = {4, 5, 6};
int* x[2];
x[0] = a;
x[1] = b;
x is array of pointers
printf("%d",*(x[1]+1));
printf("%d",*(*(x+1)+1));
Introduction to C
both statements
are identical
L10.30
Matrices and Pointers …
• The technique can be extended to
multidimensional arrays:
int a[2][3] = {{0, 1, 2},
{4, 5, 6}};
int* x[2];
x[0] = &a[0];
x[1] = &a[1];
printf("%d",*(x[1]+1));
printf("%d",*(*(x+1)+1));
printf("%d",a[1][1]);
printf("%d",*(a[1]+1));
printf("%d",*(*(a+1)+1));
Introduction to C
all statements
deliver the same
element
L10.31
Pointers to Pointers
• Pointer can refer pointers …
x
int *x;
int **y;
y
some *int
Introduction to C
some int
some int
L10.32
Strings
Strings
• Recall that C data type char is used to
represent digits, letters, and characters
char letter = 'A';
• A string is a sequence of characters. In C we
use arrays of type char for the representation
of strings. Example:
char color[] = "blue";
• The above statement declares a character
array, that is a string, and initializes it to "blue".
Introduction to C
L10.34
Strings
• Let's see what happens to memory after this
declaration and initialization
b
l
u
e \0
The null character
• Note that the string contains the character '\0';
the null character that marks the end of the
string.
• The same string could be also initialized as
follows:
char color[]={'b','l','u','e','\0'};
Introduction to C
L10.35
Strings
• Another possibility is to fix the size of the
string in declaration:
char color[10]="blue";
b
l
u
e \0 ?
?
?
?
?
• Make sure that the size of the character array
is larger than the number of characters in the
string plus the null character.
No space left for
char color[4] = "blue";
char color[5] = "blue";
Introduction to C
the null character
OK
L10.36
String Initialization
char str1[10] = "green";
OK
char str2[10] = {'g','r','e','e','n','\0'};
char str3[10];
str3 = "green"; /* !! ERROR !! */
• You can initialize a string only in the context of its
declaration.
Introduction to C
L10.37
Strings with printf and scanf
• The scanf function, when it scans a string,
skips leading whitespace characters such as
blanks, new lines and tabs. When it comes
across another whitespace character, it stops
and places the null character at the end of the
string.
• If one tries to print a string having no null
character at the end with printf, printf
continues to display the contents of memory
locations until it encounters a null character
or until it attempts across a forbidden memory
cell.
Introduction to C
L10.38
String Input/Output with
printf & scanf
#include <stdio.h>
#define STRING_LEN 10
int add (int a, int b);
int main() {
char dept[STRING_LEN], days[STRING_LEN];
int course_num, time;
printf("Enter department code, course number, days ");
printf("time like this: EB 1003 Thur 1000\n>");
scanf("%s%d%s%d", dept, &course_num, days, &time);
printf("%s %d is held %s at %d\n", dept, course_num,
days, time);
return 0;
}
Introduction to C
L10.39
String Library Function: strcpy
• The C library provides many functions to
manipulate strings; #include string.h
• strcpy:
Prototype:
char *strcpy (char *dest, char *source);
Purpose: Makes a copy of source, a string, in
the character array accessed by dest.
• Example:
char str1[10];
strcpy(str1, "EB1003-01")
str1: E
B
1
0
0
3
Introduction to C
-
0
1
\0
L10.40
String Library Function: strncpy
• strncpy:
Prototype:
char *strncpy (char *dest, char *source,
unsigned n);
Purpose: Makes a copy of up to n characters
from source in dest.
• Example:
char str1[10], str2[20]="SKU EB1003-01";
strncpy(str1, str2, 9);
str1[9] = '\0';
str1: S
K
U
E
Introduction to C
B
1
0
0
\0
L10.41
String Library Function: strncpy
• strncpy can be used to extract a number of
characters from a string. For example, you
might want to examine course code in the string
"EB1003-01"
• Example:
char str1[10] = "EB1003-01";
char course_code[5];
strncpy(course_code, &str1[2], 4);
course_code[4]='\0';
str1: E
B
1
0
0
course_code: 1
0
0
3
\0
Introduction to C
3
-
0
1
\0
L10.42
String Library Function: strcat
• strcat:
Prototype:
char *strcat (char *dest, char *source);
Purpose: Appends source to the end of dest.
• Example:
char str1[10] = "EB";
str1: E
B
\0
?
?
?
?
?
?
?
0
1
/0
strcat(str1, "1003-01");
str1: E
B
1
0
0
Introduction to C
3
-
L10.43
String Comparison
• Standard C library also provides strcmp
function to compare strings.
• strcmp:
Prototype:
int strcmp(char *s1, char *s2);
Purpose:
Compares s1 and s2 alphabetically, returns a
negative value if s1 should precede s2, zero if
s1 and s2 are equal, and a positive value if s2
should precede s1 in an alphabetized list.
Example:
char s1[10] = "Pusan", s2[10] = "Seoul";
if (strcmp(s1, s2) < 0)
Introduction to C
L10.44
String Comparisons
strcmp ("thrill", "throw");
returns a negative integer
strcmp ("read", "readable);
returns a negative integer
strcmp ("shrimp", "crab");
returns a positive integer
strcmp ("end", "end)
returns zero
Introduction to C
L10.45
String Comparison
• strncmp:
Prototype:
int strncmp(char *s1, char *s2, unsigned n);
Purpose:
Compares the first n characters of s1 and s2
returning positive, zero, and negative values as
does strcmp.
Example:
strncmp
strncmp
strncmp
strncmp
("read",
("read",
("read",
("read",
"readable",
"readable",
"readable",
"readable",
Introduction to C
1);
2);
3);
4);
All returns zero
L10.46
Scanning a Full Line
• With scanf, the strings containing spaces can
not be input at once.
• C provides the gets function to read a line of
text into a string.
char string1[20];
gets(string1);
• The gets function waits for the user to input
some text and finalized by the enter key. For
example, if we type "text string" and press
enter, string1 will be set to "text string" at
once.
Introduction to C
L10.47
Arrays of Strings
• Since a string is an array of characters, an
array of strings is a two dimensional array of
characters where each row is a string.
char week[7][10] = {"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday"};
Monday
printf("Today is %s.", week[0]);
Introduction to C
L10.48
Character Pointers
char a[] = "Hello";
a: H
e
l
l
o
\0
char *p = "Hello";
p:
H
e
Introduction to C
l
l
o
\0
L10.49
Arrays of Pointers to chars
char s1[]="March"; char s2[]="April";
char s3[]="May";
char *string[3];
string[0] = s1;
string[1] = s2;
string[2] = s3;
spring
March\0
April\0
May\0
Introduction to C
L10.50
Character Analysis
• In many string-processing applications, we need to
know if a character is a letter, a digit or a punctuation
mark. The library "ctype.h" defines such facilities:
• isalpha: If argument is a letter of the alphabet.
• isdigit: if argument is one of the ten decimal digits.
• islower (isupper): if argument is a lowercase (or
uppercase) letter of the alphabet.
• ispunct: if argument is a punctuation character.
• ispace: if argument is a whitespace character such
as a space, newline, or a tab.
Introduction to C
L10.51
The Heap /
Dynamic Memory Allocation
sizeof(...) function
• Using the sizeof function we can get
the number of bytes consumed by
instances of some datatype
Syntax: sizeof(<datatype name>);
Example:
printf("%d", sizeof(int));
Introduction to C
L10.53
The Heap
• The Heap is a special area of memory that
allows the dynamic allocation of memory
during Runtime.
• Possible Application:
Arrays with dynamic size, e.g. arrays where
we know the size only during runtime
(Remember: So far we have to specify the
size (number of elements) of some array in
the context of its declaration. E.g.: x[10])
Introduction to C
L10.54
Heap Management in C
• Three functions for heap management
defined in stdlib.h
– calloc(n, el_size) – allocation of continuous
space for an array of n elements with el_size
bytes for each array element
– malloc(size) – allocation of an area of size
bytes in the heap
– free(p) – freeing of allocated heap-space. (C
stores internally the amount of memory associated
with p)
Introduction to C
L10.55
Warning:
Dangling Pointer Problem
• Don’t use pointers that refer to some freed
memory area
• Example:
int *p;
p = malloc(sizeof(int));
…
free(p);
p is here a “dangling pointer”. This
…
statement can create serious trouble.
*p = 5;
Introduction to C
L10.56
“void” pointers in C
• malloc returns a pointer of type void*. The typechecker of C is quite tolerant with this type of
pointers. Example:
The following code generates no error during compile
time (not even a warning)!
void* fun () {
return NULL;
}
void main() {
int *p;
p = fun();
}
Introduction to C
L10.57