Lecture 13: Arrays, Pointers, Code examples
B Burlingame
2 Dec 2015
Announcements Final exam: Dec 10, 9:45 AM Homework 8 & Final Lab due Dec 10 with
the final Final review
Extra credit opportunity Find an academic paper related to this class
in some way Read it and write a one page synopsis Turn in the synopsis and the paper it relates
to with the final
Recall: what is an array?
Index No. [0] [1] [2] [3 [4] [5] [6] [7] [8] [9]int nums [10];
Element No. 1 2 3 4 5 6 7 8 9 10
int nums [10]; 10 element array of integers
Element no. 3 is accessed by:nums [2]
because indexing begins at 0
Passing an Array to a Function Prototype and
function header need:
data type array name [ ]
Function call with actual name of array
Note: in the function prototype and function header
char *array would also work
#include <stdio.h>void PrintArray(int elements, char array[]);int main(){
/* initialize the array */ char test[]={'M','E','3','0'};
/* get the size of the array */int num_elem=sizeof(test)/sizeof(char);
/* pass array to function */
PrintArray(num_elem, test); return 0;}/* PrintArray() function definition */void PrintArray(int num_elem, char array[]){ int i=0; for(i=0; i<num_elem; i++)
{ printf("test[%d]==%c",i,array[i]); printf(" @ 0x%p\n",&array[i]); }}
How do pointers and arrays relate?
Index No. [0] [1] [2] [3 [4] [5] [6] [7] [8] [9]int nums [10];
Element No. 1 2 3 4 5 6 7 8 9 10Offset +0 +1 +2 +3 +4 +5 +6 +7 +8 +9
Address 0x0 0x4 0x8 0xC 0x10 0x14 0x18 0x1C 0c20 0x24
int nums [10]; 10 element array of integers
Element no. 3 is accessed by: nums [2]- or -
Element no. 3 can be access by: *(num + 2)
Where num is the head address of the array and 2 is the offset
Passing an Array Pointer to a Function
Prototype and function header need:
data type array name
(as pointer) Function call
with actual name of array
#include <stdio.h>void PrintArray(int elements, char *array);int main(){
/* initialize the array */ char test[]={'M','E','3','0'};
/* get the size of the array */int num_elem=sizeof(test)/sizeof(char);
/* pass array to function */
PrintArray(num_elem, test); return 0;}/* PrintArray() function definition */void PrintArray(int num_elem, char *array){ int i=0; for(i=0; i<num_elem; i++) { printf("test[%d]==%c",i, *(array + 1)); printf(" @ 0x%p\n", array + 1); }}
Pointers and Arrays An array is basically a static pointer to the
head (element 0) of an arrayvoid show_array( int x[], int *y, int size );
int main( void ){ int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; //since arrays are already storing addresses, no & necessary show_array( a, a, 10 ); return 0;}
void show_array( int x[], int *y, int size ){ int i = 0; for( i = 0; i < size; ++i ) { //note how the array and pointer notation looks printf( "%d\t%d\n", x[i], *(y + i) ); }}
Pointers and Arrays An array is basically a static pointer to the
head (element 0) of an arrayvoid show_elem( int *x, int *y );
int main( void ){ int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; //an element of an array, still stores a value; therefore an & is
//necessary. Using the pointer offset method, however, doesn’t
show_elem( a + 3, &a[3] ); return 0;}
void show_elem( int *x, int *y ){
printf( “%d\t%d\n”, *x, *y );}
Examples
Problem Statement
Prompt the user for a string Convert the string to lower case Display the lower case version of the
string
Calling program#include <stdio.h>
void lc(char s[]); // Convert a string to all lowercase
int main(void){ char string1[100] = ""; // Declare a sizeable string char buffer[100] = ""; // Declare a buffer
printf("Enter a string: "); // Prompt the user for a string fgets(buffer, sizeof(buffer), stdin); // Read string as a line from the sscanf(buffer, "%s", string1); // keyboard (assumed as stdin)
lc(string1); // Convert the string to lower case printf("%s is lower cased\n", string1); // print the string to the display
return 0;}
Convert to lower casevoid lc(char s[]){ unsigned int i = 0; int utoc = 'A' - 'a'; // recall that characters are just numbers for (i = 0; s[i] != '\0'; ++i) // iterate over entire string { if (s[i] >= 'A' && s[i] <= 'Z') // if the letter is upper case { s[i] = s[i] - utoc; // subtract the difference between the } // upper and lower case values }} // recall that arrays and strings are // effectively pointers, so the change // is permanent
Problem
Compare two strings for equivalence Equivalence means they are the same
length with the exact same characters
Calling program#include <stdio.h>int strcmp(char str1[], char str2[]);
int main(void) { char string1[100] = ""; char string2[100] = ""; char buffer[100] = ""; printf("Enter a string: "); // Obtain two strings from the user fgets(buffer, sizeof(buffer), stdin); sscanf(buffer, "%s", string1);
printf("Enter a string: "); // Obtain second string fgets(buffer, sizeof(buffer), stdin); sscanf(buffer, "%s", string2);
if (strcmp(string1, string2)) { // Compare the strings for equivalence printf("%s and %s are equal\n", string1, string2); } else { printf("%s and %s are NOT equal\n", string1, string2); } return 0;}
Comparing two strings//compare two strings, return 1 if they are equivalent, //else return 0int strcmp( char str1[], char str2[] ){ unsigned int i = 0; // go through each string, line by line for( i = 0; str1[i] == str2[i] && str1[i] != '\0' && str2[i] != '\0‘; ++i ) //continue if the chars are equal and the ends haven’t been found { // do nothing in the loop } if( str1[i] == str2[i] ) { return 1; } else { return 0; }}
Comparing two string, alternateint strcmp( char *str1, char *str2 ){ unsigned int i = 0; // go through each string, line by line while( *(str1 + i) == *(str2 + i) && *(str1 + i) != '\0' && *(str2 + i) != '\0' ) { ++i } // check the final character for return values if( *(str1 + i) == *(str2 + i) ) { return 1; // true, the strings are the same } else { return 0; // false, the strings are not the same }}
Problem Statement
Read through a file of numbers One floating point number per line
Add the numbers Count the numbers Find the average Display all three
Calling Program#include <stdio.h>
void stats(FILE *fh, int *count, double *sum, double *average);
int main(void){ FILE *infile = fopen("c:/temp/data.dat", "r"); // Open the file int count = 0; double sum = 0.0; double average = 0.0;
if (infile == NULL) // Ensure the file { // opened correctly fprintf(stderr, "Error opening c:/temp/data/dat.\n"); // report an error, if return 1; // it didn’t }
stats(infile, &count, &sum, &average); // Generate the stats printf("Count: %d\n", count); // Report the results printf("Sum: %6.3lf\n", sum); printf("Average: %6.3lf\n", average);}
Generate Statsvoid stats(FILE *fh, int *count, double *s, double *ave){ double value = 0.0; // Storage for the current value
while (fscanf(fh, "%lf", &value) != EOF) // Read until end of file (EOF) is { // found ++(*count); // increment the counter *s += value; // add to the sum } // sum is a type of accumulator
*ave = *s / *count; // calculate the arithmetic mean } // (the average)
Alternate#include <stdio.h>#include <stdlib.h>
FILE* open_input_file(char path[]);void generate_stats(FILE *fh, int *count, double *sum, double *average);void display_stats(int count, double sum, double average);
#define PATH "c:/temp/data.dat"
int main(void){ int count = 0; double sum = 0.0; double average = 0.0;
FILE *infile = open_input_file(PATH); // Note: the pseudocode is generate_stats(infile, &count, &sum, &average); // written in the function names display_stats(count, sum, average); // open input files} // generate stats // display stats
FILE* open_input_file(…)FILE* open_input_file(char path[]) // simply open the file{ // and confirm that it FILE *fh = fopen(path, "r"); // opened correctly if (fh == NULL) { fprintf(stderr, "Error opening c:/temp/data/dat.\n"); exit(1); // premature program } // termination, from // stdlib.h return fh;}
void generate_stats(…)void generate_stats(FILE *fh, int *count, double *s, double *ave){ double value = 0.0; // This is the same as stats while (fscanf(fh, "%lf", &value) != EOF) // from the previous rendition { ++(*count); *s += value; }
*ave = *s / *count;}
void display_stats(…)void display_stats(int count, double sum, double average){ printf("Count: %d\n", count); // Very simple though useful routine printf("Sum: %6.3lf\n", sum); // It puts all of the output in one printf("Average: %6.3lf\n", average); // clearly defined location}