CS计算机代考程序代写 gui Pointers and Arrays

Pointers and Arrays

Class 21

Whole-Array Assignment
• I would like to copy an entire array’s values to another array

#define SIZE 4
int array1[] = {-2, -1, 0, 1};
int array2[SIZE];

array2 = array1;

• this will not work!
• remember: the name array1 refers to the address of the first

byte of the first element of array1
• array2 = array1; is interpreted as, “change the place where

array2’s first byte is to the same place where array1’s first byte
is”
• but you cannot move the place where a variable is located in

memory to a different place

Whole-Array Assignment
• I would like to copy an entire array’s values to another array

#define SIZE 4
int array1[] = {-2, -1, 0, 1};
int array2[SIZE];

array2 = array1;

• this will not work!
• remember: the name array1 refers to the address of the first

byte of the first element of array1
• array2 = array1; is interpreted as, “change the place where

array2’s first byte is to the same place where array1’s first byte
is”
• but you cannot move the place where a variable is located in

memory to a different place

Whole-Array Assignment

• the only way to copy an array’s values to another array is
element-by-element

size_t index;
for (index = 0; index < SIZE; index++) { array2[index] = array1[index]; } Whole-Array Comparison • I would like to see if two arrays have the same elements int array1[] = {-2, -1, 0, 1}; int array2[] = {-2, -1, 0, 1}; array1 == array2 /* should be true? */ • this will not work! • remember, array1 is just an address (say, 0x861a) • and array2 is a different address (say, 0x862c) • array1 == array2 really means 0x861a == 0x862c, which is clearly false Whole-Array Comparison • I would like to see if two arrays have the same elements int array1[] = {-2, -1, 0, 1}; int array2[] = {-2, -1, 0, 1}; array1 == array2 /* should be true? */ • this will not work! • remember, array1 is just an address (say, 0x861a) • and array2 is a different address (say, 0x862c) • array1 == array2 really means 0x861a == 0x862c, which is clearly false Whole-Array Comparison • the only way to compare an array’s values to another array is element-by-element • what would the code for this look like? unsigned same = 1; size_t index = 0; while (same && index < SIZE) { same = array1[index] == array2[index]; index++; } return same; Whole-Array Comparison • the only way to compare an array’s values to another array is element-by-element • what would the code for this look like? unsigned same = 1; size_t index = 0; while (same && index < SIZE) { same = array1[index] == array2[index]; index++; } return same; Array Elements as Function Parameters • array elements are simple variables • they can be used anywhere “normal” variables can unsigned values[] {10, 15, 20}; unsigned remainder; ... remainder = compute_modulus(values[2], values[0]); • the two parameters are pass by value • any changes made to them in the function do not affect the array, because the values are copied into the function Pointer Parameters • a pointer can easily be a parameter to a function • let’s look at pass-by-pointer functions 1 void get_number(int* input); 2 void double_value(int* value); 3 4 int main(void) 5 { 6 int number; 7 8 get_number(&number); 9 double_value(&number); 10 printf("the value you entered, doubled, is %d\n", number); 11 return 0; 12 } 13 void get_number(int* input) 14 { 15 printf("enter an integer: "); 16 scanf("%d", input); 17 } 18 void double_value(int* value) 19 { 20 *value *= 2; 21 } Arrays as Function Parameters • an array name is the starting address of the array in memory • an array cannot be copied in one step, but only one element at a time • thus an array cannot be passed by value into a function • arrays can only be passed by pointer into a function • because an array’s name is simply the address of the array, it already is a pointer Arrays as Function Parameters • an array name is the starting address of the array in memory • an array cannot be copied in one step, but only one element at a time • thus an array cannot be passed by value into a function • arrays can only be passed by pointer into a function • because an array’s name is simply the address of the array, it already is a pointer 1 #define SIZE 6 2 void show_values(int values[], size_t size); 3 4 int main(void) 5 { 6 int numbers[] = {5, 10, 15, 20, 25, 30}; 7 8 show_values(numbers, SIZE); 9 return 0; 10 } 11 12 void show_values(int values[], size_t size) 13 { 14 size_t index; 15 for (index = 0; index < size; index++) 16 { 17 printf("%d ", values[index]); 18 } 19 printf("\n"); 20 } Arrays as Function Parameters • several important things to note • lines 2 and 12: empty square brackets denote this is an array parameter • an array parameter is a pointer parameter • lines 2 and 12: we must pass the size of the array to the function because otherwise the function cannot determine the array size • since an array passed to a function is a pointer, a change made to the array inside a function does affect the array in the calling scope const Array Parameters • the fact that you cannot pass an array by value is problematic • for “normal” variables, if you do not want a function to change their value, you use pass by value • this prevents any change from affecting the calling scope • but you cannot pass an array by value • how do you prevent the function from being able to alter the array? • you declare a const array parameter • always declare an array parameter const if the function will not change the array 1 void show_values(const int values[], size_t size); 2 3 int main() 4 { 5 int numbers[] = {5, 10, 15, 20, 25, 30}; 6 7 show_values(numbers, SIZE); 8 return 0; 9 } 10 11 void show_values(const int values[], size_t size) 12 { 13 size_t index; 14 for (index = 0; index < size; index++) 15 { 16 printf("%d ",values[index]); 17 } 18 printf("\n"); 19 } Syntactic Sugar • int array[] and int* array are identical • so the previous prototype could just have easily been written: void show_values(const int* values, size_t size); C-Strings • a C-string is an array of characters • after the “real” characters, the final character is the null character, the character with ASCII code 0 • the null character is written ’\0’ • ’\0’ is just 0, but emphasizes it’s a character • a string literal enclosed in double quotes is stored in memory as a null-terminated C-string: "foobar" is ’f’ ’o’ ’o’ ’b’ ’a’ ’r’ ’\0’ C-String Variables • you can declare C-string variables char name[5] = "foo"; char name[] = "foo"; ’f’ ’o’ ’o’ ’\0’ ? ’f’ ’o’ ’o’ ’\0’ • a three-character string occupies four array elements • one element is required for the null character C-string Output • once a C-string (an array of characters) exists, it can be used for output char name[10] = "Fred"; printf("%s\n", name); • printf stops outputting characters when the null character is encountered • regardless of the array size ’F’ ’r’ ’e’ ’d’ \0 ? ? ? ? ? The Null Character • everything about a C-string depends on the null character • if something happens to that null character, everything goes south char stuff[] = "foobar"; char name[] = "Ann"; /* name[3] is \0 */ name[3] = 'x'; /* replace \0 with x */ printf("%s\n", name); output: Annxfoobar • once the null character is gone, printf doesn’t know where to stop • printf keeps going until it reaches a byte equal to zero A Subtle Error 1 int main(void) 2 { 3 char foo[] = "foobar"; 4 char name[5] = "Becky"; 5 printf("%s\n", name); 6 return 0; 7 } output: Beckyfoobar gets • K&R blithely talk about the gets routine for string input • NEVER use gets • show test_gets.c • however, fgets is safe and is used extensively • show echo_fgets.c • fgets notes: • will read at most MAX - 1 characters • reads the newline character and stores it in the string also Array of Strings • a C-string is an array of chars • we can have an array of C-strings, which is an array of an array of char char* poem[] = {"Roses are red", "Violets are blue", "Sugar is sweet", "Wish you were, too."}; • when you define an array of strings, the index before the last must be given, explicitly or implicitly Legal: char poem[4][] = {"Roses are red", "Violets are blue", "Sugar is sweet", "Wish you were, too."}; Illegal: char poem[][] = {"Roses are red", "Violets are blue", "Sugar is sweet", "Wish you were, too."}; char** poem = {"Roses are red", "Violets are blue", "Sugar is sweet", "Wish you were, too."}; Declaration • but a declaration (e.g., function prototype) does not contain size information • all these are ok: char** poem ← this is typically preferred char* poem[] ← this is ok also char poem[][] ← rarely used for an array of strings Command Line Arguments • main can call any other function in your program • but what calls main? • the operating system calls main for you when you invoke the program, by entering the program’s name at the terminal prompt, or by double-clicking on the program on a GUI • when the operating system calls main, it passes the command line arguments to main as actual parameters main Parameters • so far, our main function has had no parameters • but two formal parameters are in fact defined for it 1. argc: an integer that is the count of arguments 2. argv: an array of strings, i.e., an array of arrays of characters, which are the arguments themselves as strings argv stands for “vector of arguments” int main(int argc, char** argv) { ... main Parameters int main(int argc, char** argv) { ... • argc tells how many command line arguments were passed to main (just like BASH $#) • there is always one argument (argv[0]), which is the name of the program itself (just like BASH $0) • the other arguments (if any) are strings that can be addressed as array elements argv[1], argv[2], etc (just like BASH $1 $2 etc) main Parameters a simple program to echo command line arguments to screen int main(int argc, char** argv) { size_t index; for (index = 0; index < argc; index++) { printf("%zu: %s\n", index, argv[index]); } return 0; } run echo_command_line A More Substantial Program $ cp -av /tmp/toy_wc.c . $ rsync -vutz .edu:/tmp/toy_wc.c .