Observera att detta är en arbetsversion av sidan!
Dölj style3dev.css för att bli av med annoteringarna!

Lesson 2: Arrays

Purpose: Learn how to use arrays.
Contents: One dimensional arrays, character strings.
References: C Programming in wikibooks and/or C tutorial in tutorialspoint.

Arrays

An array is a collection of several elements all of the same type.

Facts about arrays in C:

Example 1

This example demonstrates
  1. how to declare an array,
  2. how to read values into an array,
  3. how to sort an array and
  4. how to print an array.
Code Explanation
int main() { printf("Number of items to sort: "); int n; scanf("%d", &n); int a[n]; We need to know the number of elements in order to declare the array. Thus, ask the user.
(Actually, this is not so good - the program should really be able to count the data. We will deal with this later on.)
printf("Enter the %d values: ", n); for (int i = 0; i < n; i++) { scanf("%d", &a[i]); } Ask the user to enter the values.
Note, as usual, that we have to give the address to the element using the & operator!
for (int i = 0; i < n-1; i++) { int indMin = i; for (int j = i + 1; j < n; j++) { if (a[j] < a[indMin]) { indMin = j; } } int temp = a[i]; a[i] = a[indMin]; a[indMin] = temp; }

This is the selection sort algorithm. It is simple but not efficient for large number of elements.

The idea is first to exchange the smallest element with the first element, then the smallest of the remaining with the second etc.

for (int i = 0; i < n; i++) { printf("%6d ", a[i]); if (i%4 == 3) { printf("\n"); } } Print. Take a new line after every group of four values.
}

Copy the program and try it!

Example 2

This example shows how an array can be used to count character frequencies read from standard input.
Code Explanation
#include <stdio.h> #include <ctype.h> int main() { We include ctype.h because we want to use the function isprint(c) to decide if a character code stands for a printable character.
const int size=128; int freq[size]; We will only look at character values between 0 and 127.
for (int i=0; i < size; i++) { freq[i] = 0; }

The content of an array, as well as ordinary variables, is undefined from the beginning.
Thus the array must be initialized to 0.

int c = getchar(); while (c != EOF) { freq[c]++; c = getchar(); } Read from standard input.
Increase the appropriate counter.
for (int i=0; i < size; i++) { if (isprint(i)) { printf("%6d '%c'%4d, ", i, i, freq[i]); if (i%4 == 3){ printf("\n"); } } } Iterate over all codes but print only the printable ones
printf("\n"); }
Copy the program and try it with its own source code as input:

./charFrequencies < charFrequencies

Arrays as parameters to functions

When an array is used as parameter to a function no information about the size is transferred. Actually, the only information that is passed is the address of the first element. This means that, unless the size of the actual array is globally known, the real size must be given as a parameter too.

Example: A print function for arrays

Code Explanation
void printArray(double a[], int n) { printf("["); for (int i = 0; i < n; i++) { printf("%.2lf", a[i]); if (i < n-1) { printf(", "); } } printf("]"); } The function takes an array (of unknown size) and prints out the n first elements separated by commas and enclosed by [].

Example: A read function for arrays

Lets first think of the function head. What about this:
void readArray(double a[]) { ...

As we said above, it is the address of the first element that is transferred to the function. That means that it is perfectly OK to store values in the array and these values will show up in the caller's array. There is actually only one array.

Thus, the caller has to provide the array but he may not know how large the array should be.

For simplicity, we start with assuming that the caller provides an array large enough.

The second problem is that the function should tell the caller the number of values that actually have been read. There is no way for the caller to know that unless the function provides this information.

Can we do that using a parameter?

void readArray(double a[], int n) { ... ... n = number of read values

No, that is not possible since C uses the "call by value"-method for parameter handling which means that values are transferred at entry but nothing is transferred back at exit.

The problem could be solved by asking the caller to give the address to a place where to store the number of read values. This method is used scanf. However, in this case it is easier to return the information as a function value.

The function scanf has a return value which we have ignored up to now. It returns the number of successful read operations. Since we will read one double for each call to scanf, it should return 1 when it did work and 0 when it didn't. This leads us to the function:

Code Explanation
int readArray(double a[]) { int i = 0; while (scanf("%lf", &a[i])==1) { i++; } return i; }

The reading ends when the user enters something that can not be interpreted as a floating point number.

Still a very unsafe function!

Exercises

  1. Copy this program, compile and run it. See what happens if you enter more than 5 numbers!
  2. Write a function for computing the Euclidian vector norm. The sqrt is declared in the math.h which should be imported.
  3. Modify the readArray function by adding a parameter telling the size of the array provided. Suggest some action when the user enters too many values.

Character strings

The convention to terminate strings with the null character makes it possible to manipulate strings without explicitly specifying the length.

Example: Calculate the length of a string.

int strlen(char s[]) { int n = 0; while (s[n] != '\0') { n++ } }

The function strlen i actually in the string-library so we don't have to write it ourselves.

Note that the convention makes it possible to calculate the length of the string, not of the array containing the string. For example, the statement

char s[100] = "Hello!";
defines an array of size 100 but uses only the first 7 positions.

Some functions in the string library

Function Explanation
int strlen(char s[]) Returns the length of the string
void strcpy(char s1[], char s2[]) Copies the string from s2 to s1
void strcat(char s1[], char s2[]) Concatenates s2 with s1
int strcmp(char s1[], char s2[]) Compares s1 to s2. An integer is returned that is less than, equal to, or greater than zero depending on whether s1 is lexicographically less than, equal to, or greater than s2.

The declarations are somewhat simplified regarding parameter types and return values.

On Unix type systems, the man string-command can be used to get more functions and man function to get information on a particular function.

Exercises

  1. Write a function void readWord(char word[]) that reads a word from standard input and puts it into the array word. By "word" we mean any sequence of characters not containing space (' '), or line break ('\n'). You may assume that the array is large enough to store the word. The string should of course be terminated by the null character.
    Hint: Use getchar to read individual characters.
  2. Write a program that reads words from standard input and calculates and prints the length of the longest word. Assume that no word contains more than 99 characters.
  3. Modify the program so that it also tells which the longest word is. Hint: Use the strcpy.

Go to next lesson.

Valid CSS!