Sei sulla pagina 1di 34

CS1010E Lecture 8

Arrays
Henry Chia
hchia@comp.nus.edu.sg

Semester 1 2011 / 2012


Department of Computer Science
School Of Computing
National University Of Singapore

CS1010E Lecture 8 p.1/34

Lecture Outline
One-Dimensional Arrays
Declaration and initialization
Array element access
Arrays and pointers
Arrays as function arguments
File Processing
File Input
File Output

CS1010E Lecture 8 p.2/34

Problem Statement #1
Read 100 values and find the average.
Requires one pass through the values.
#include <stdio.h>
#define MAX 100
int main(void)
{
int i, val, sum=0;
double ave;
for (i = 1; i <= MAX; i++)
{
scanf("%d", &val);
sum += val;
}
ave = 1.0 * sum / MAX;
printf("The average is %lf\n", ave);
return 0;
}
CS1010E Lecture 8 p.3/34

Problem Statement #2
Read 100 values from the user and find the
number of values greater than the average.
Requires two passes through the values.
Pass #1: Find the average.
Pass #2: Count values greater than the average.

Program design:
Declare 100 variables for input values.
Read and compute the sum of all values.
Compute the average.
Determine how many variables have values greater
than the average using 100 if statements.
CS1010E Lecture 8 p.4/34

One-Dimensional Arrays
Work with a set of data values of the same
type without giving each value a separate
name.
An array is given an identifier name.
Subscripts distinguish between array values.
Subscripts start with 0 and increment by 1.
Memory assignment for an array is
guaranteed to be a sequential group of
memory locations.

CS1010E Lecture 8 p.5/34

One-Dimensional Arrays
@100

s:

@101 @102

@103 @104

@105

-1

15

s[0]

s[1]

s[2]

s[3]

s[4]

s[5]

First value in array s is s[0]; last (sixth)


value is s[5].
s is a symbolic address to the first value; it is
not a variable. In the above, s is @100.

Memory location for s[1] will immediately


follow the memory location for s[0], etc.
Actual addresses of adjacent elements might
not differ by one, but by a fixed offset.
CS1010E Lecture 8 p.6/34

Array Declaration
An array identifier is followed by an integer
expression in brackets that specifies the
maximum number of elements in the array.
Elements in an array must be the same data
type, eg.
int s[6];
double list[100];
struct Fraction fracArray[50];
int *ptr[10];
int *ptr[10]

is a declaration of an array of ten pointers to

integers. This is different from int

(*ptr)[10]

which is a

pointer to an array of ten integers.


CS1010E Lecture 8 p.7/34

Declaration and Initialization


An array can be initialized during declaration.
To initialize the array, values are specified
(comma-separated) in an initializer list.
int s[6]={5,0,-1,2,15,2};
Initializer lists may be shorter than the array
size. The following are equivalent.
int s[6]={5};
int s[6]={5,0,0,0,0,0};
To zero the entire array: int s[6]={0};
Initializer lists used only during declaration.
CS1010E Lecture 8 p.8/34

Declaration and Initialization


If an array is specified without a size, but with
an initialization sequence, the size is defined
to be equal to be equal to the number of
values in the sequence, as follows:
int s[]={5,0,-1,2,15,2};
double t[]={0.0,0.1,0.2,0.3};
The size of an array must be specified in the
declaration statement by using either a
constant within brackets or by an initialization
sequence within braces.

CS1010E Lecture 8 p.9/34

Declaration and Initialization


main
int main(void)
{
int s[6] = {0};
double t[10],
r = 1.0;
return 0;

s: 0 0 0 0 0 0
t: ? ? ? ? ? ? ? ? ? ?
r 1.0

Arrays are represented as a series of boxes


within the function in which they are declared.
Array identifiers (s and t) refer to the first element of their respective arrays.
CS1010E Lecture 8 p.10/34

Assigning Array Elements


Arrays are assigned by assigning individual
array elements.
For example, to fill a double array g with 21
values 0.0, 0.5, 1.0, 1.5, . . . , 10.0.
int k;
double g[21];

// declare array

for (k=0; k<21; k++)


g[k] = k*0.5; // assign array element

Looping condition must ensure a final loop


with k as 20, and not 21, since the array
elements are g[0] through g[20].
CS1010E Lecture 8 p.11/34

Assigning Array Elements


It is a common mistake to specify a subscript
that is one value more than the largest valid
subscript.
This error can be difficult to find because it
accesses values outside the array.
This can produce execution errors such as
segmentation fault or bus error.
Often, this error is not detected during
program execution, but will cause
unpredictable program results, since your
program has modified a memory location
outside of your array.
CS1010E Lecture 8 p.12/34

Problem #2 Revisited
#include <stdio.h>
#define MAX 100
int main(void)
{
int count=0, sum=0, data[MAX], i;
double ave;
for (i = 0; i < MAX; i++)
{
scanf("%d", &(data[i]));
sum += data[i];
}
ave = 1.0 * sum / MAX;
for (i = 0; i < MAX; i++)
if (data[i] > ave) count++;
printf("%d values greater than %lf\n", count, ave);
return 0;
}
CS1010E Lecture 8 p.13/34

Computation with Array Elements


If s refers to an array of type t, then s[i] is a
variable of type t.
Computations with array elements are
specified just like computations with simple
variables, but a subscript must be used to
specify an individual array element.
Incrementing: (s[i])++; s[i]=s[i]+1;
Function arguments: sqrt(d[i]);
Function return: return d[i];
Condition check: if (d[i] > 100)
Input: scanf("%d", &(s[i]));
Output: printf("%d\n", s[i]);
CS1010E Lecture 8 p.14/34

Arrays and Pointers


Since an array identifier is an address of the
first element of the array, this address can be
stored in a pointer variable.
int s[6]={5,0,-1,2,15,2}, *ptr;
...
ptr = s;

s:

@100

@101

@102

@103

@104

@105

-1

15

ptr @100

CS1010E Lecture 8 p.15/34

Arrays and Pointers


The following table shows the equivalence
between array/pointer subscript/dereference.
Assuming the assignment: ptr = s;
Array subscript Pointer subscript Pointer dereference
s

ptr

ptr

s[0]

ptr[0]

*ptr

s[i]

ptr[i]

*(ptr+i)

&s[i]

&ptr[i]

ptr+i

ptr+i is the address of the ith element after


the element located at ptr.
CS1010E Lecture 8 p.16/34

Arrays and Pointers


To make ptr point to the next element s[1],
ptr = &(s[1]); // assign addr of s[1]
ptr = ptr + 1; // point to the next element
ptr += 1; // or
s:

ptr++;

or

++ptr;

@100

@101

@102

@103

@104

@105

-1

15

ptr @101

CS1010E Lecture 8 p.17/34

Arrays and Pointers


Integers can be added (subtracted) to (from) pointers.
Two pointers can be subtracted to find their offset.
ptr2 = ptr1 + 3;
(*ptr2)++; // different from ptr2++;
printf("ptr1 is %d away from ptr2\n",
ptr2 - ptr1);
ptr1 @100

s:

@100

@101

@102

@103

@104

@105

-1

15

ptr2 @103

CS1010E Lecture 8 p.18/34

Pointer Comparisons in Arrays


Apart from relational operators == and !=,
other relational operators <, >, <=, >= can be
used to compare relative locations between
pointers referencing elements within the
same array.
if (ptr2 > ptr1)
printf("ptr2 is %d elements right of ptr1.\n",
ptr2 - ptr1);
else
printf("ptr2 is %d elements left of ptr1.\n",
ptr1 - ptr2);

CS1010E Lecture 8 p.19/34

Array Element as Function Argument


Pass-by-value: When an array element is
used as argument in a function call, the value
is passed to the parameter in the function.
int main(void)
{
int s[6]={5,0,-1,2,15,2};
swap(s[1],s[4]);
// swapped?
printf("%d %d", s[1], s[4]);
return 0;
}
void swap(int x, int y)
{
int temp = x;
x = y;
y = temp;
return;
}
CS1010E Lecture 8 p.20/34

Array as Function Argument


Pass-by-(address)-value: When an array is
used as an argument in a function call, the
address of the array is passed to the function
and not the entire set of values in the array.
Array addresses are stored in pointer
parameters. Using this address, the function
can now refer to values in the original array.
Because a function accesses the original
array values, we must be very careful that we
do not inadvertently change values in an
array within a function.
CS1010E Lecture 8 p.21/34

Array as Function Argument


int main(void)
{
int s[6]={5,0,-1,2,15,2};
swap(s,1,4);
printf("%d %d", s[1], s[4]);
return 0;
}
void swap(int *list, int x, int y)
{
int temp;
// temp = *(list+x);
temp = list[x];
list[x] = list[y]; // *(list+x) = *(list+y);
list[y] = temp;
// *(list+y) = temp;
return;
}

CS1010E Lecture 8 p.22/34

Array as Function Argument


Since parameter list in function swap is a pointer
variable, list can be re-assigned.
To indicate that parameter list refers to an array
rather than single variables, we may declare list as
int list[].
The actual parameter type of int *list and
int list[] is the same, i.e. <int *>.
main

@1
s: 5 0 -1 2 15 2

swap

6
list

swap(s,1,4);
@1, 1, 4

@1

4
CS1010E Lecture 8 p.23/34

Arrays as Function Arguments


Typically when information in an array is passed to a
function, two parameters are usually used: the array,
and the number of array elements to be processed.
void printArray(int list[], int numElem)
{
int i;
for (i = 0; i < numElem; i++)
printf("%d ", list[i]);
printf("\n");
return;
}

A common error is to declare the parameter as


int list[numElem]; recall that parameter list is
merely a pointer variable storing an address value.
CS1010E Lecture 8 p.24/34

Modularity with Arrays


Arrays must be declared in the function with the
longest duration for which an array remains accessible;
typically in the main function.
Arrays must be declared with a specific size that is as
large as, or larger than, the maximum number of
values to be stored into them.
It is common for the size of an array to be specified as
a symbolic constant; do not declare an array with a
variable as its size.
Question to ponder...
Suppose function f calls function g. Can an array
declared in g be returned to f ?
CS1010E Lecture 8 p.25/34

Modularity with Arrays


#include <stdio.h>
#define MAX 100
double getAverage(int data[], int numElem);
int countAboveAverage(int data[], int numElem, int ave);
int main(void)
{
int count=0, sum=0, data[MAX], i;
double ave;
for (i = 0; i < MAX; i++)
scanf("%d", &(data[i]));
ave = getAverage(data,MAX);
count = countAboveAverage(data,MAX,ave);
printf("%d values greater than %lf\n", count, ave);
return 0;
}
CS1010E Lecture 8 p.26/34

Modularity with Arrays


double getAverage(int data[], int numElem)
{
int i, sum=0;
for (i = 0; i < numElem; i++)
sum += data[i];
return 1.0 * sum / numElem;
}
int countAboveAverage(int data[], int numElem, int ave)
{
int i, count=0;
for (i = 0; i < numElem; i++)
if (data[i] > ave) count++;
return count;
}

CS1010E Lecture 8 p.27/34

File Input
Arrays are often used to store large amounts
of information that is read from data files.
Typically, reading the file requires
opening the file
testing if the file was successfully opened
reading the file
closing the file
The template in the next slide is used to read
a file named input.txt into an array.

CS1010E Lecture 8 p.28/34

File Input
#include <stdio.h>
int main(void)
{
FILE *inFile;
inFile = fopen("input.txt","r");
if (inFile == NULL)
{
printf("File open error!\n");
return 0;
}
// read the file and continue processing.
fclose(inFile);
return 0;
}

CS1010E Lecture 8 p.29/34

File Input
inFile = fopen("input.txt","r");

opens the file input.txt and if successful, returns


a valid file stream object, otherwise NULL (i.e. 0) is
returned.
"r" argument signifies that the file is to be read.
if (inFile == NULL)
TRUE if file could not be opened and take
appropriate action.
fclose(inFile)

closes the file after opening and reading.

CS1010E Lecture 8 p.30/34

File Input
Reading the file for a pre-known number of
data records (eg. 100 records where each
record is an integer value),
for (i = 0; i < 100; i++)
fscanf(inFile, "%d", &data[i]);

Usage of fscanf is the same as scanf,


except for the first FILE stream argument.
If each record is one integer value, followed
by another floating point value, then
fscanf(inFile, "%d %lf", &data[i], &val[i]);

CS1010E Lecture 8 p.31/34

File Input
Read the file for an unknown number of
records,
i = 0;
while (fscanf(inFile, "%d", &data[i]) == 1)
i++;

fscanf returns the number of successful


reads. If end-of-file is reached, fscanf
returns -1 (not zero).

If each record is one integer value, followed


by another floating point value, then
while (fscanf(inFile, "%d %lf",
&data[i], &val[i]) == 2)
i++;
CS1010E Lecture 8 p.32/34

File Output
int main(void)
{
FILE *outFile;
outFile = fopen("input.txt","w");
if (outFile == NULL)
{
printf("File open error!\n");
return 0;
}

// use "w"

// write the file using fprintf


fclose(inFile);
return 0;
}

Use fprintf to write to a file,


for (i = 0; i < 100, i++)
fprintf(outFile, "%d\n", data[i]);
CS1010E Lecture 8 p.33/34

Lecture Summary
One-dimensional arrays.
Declaration and initialization.
Array elements as single variables.
Arrays as function arguments
(pass-by-address).
File processing templates.
Count-controlled file input.
Sentinel-controlled file input.
File output.

CS1010E Lecture 8 p.34/34

Potrebbero piacerti anche