300 likes | 307 Views
Learn about arrays, structs, and strings in C programming. Understand the concepts, syntax, and functions related to these data structures. Improve your understanding of memory allocation, passing arrays to functions, and working with strings.
E N D
Programming in C Arrays, Structs and Strings
Arrays • An array is a collection of individual data elements that is: • Ordered -- we can count off the elements 0,1,2,3,... • Fixed in size • Homogeneous -- all of the elements have to be of the same type, e.g., int, float, char, etc. • In C, each array has two fundamental properties: • the element type • the size
Array Example The following code declares an array of 100 integers and initializes the first and last element. Note that C arrays are always indexed from 0 (zero) int scores[100]; scores[0] = 17; scores[99] = 42;
. . . . . . . . . . . . 98 99 0 1 Arrays in Memory • The name of the array refers to the whole array by acting like a pointer (the memory address) of the start of the array scores Someone else’s memory Don’t read/write here
2-d Arrays • The following code declares a 2-d array of ints and initializes the first and last elements int board[10][12]; board[0][0] = 13; board[9][11] = 42; • Although conceptually a table with rows and columns, 2-d arrays are implemented as a single contiguous block of memory with elements of the rightmost index next to each other. E.g. board[1][8] comes right before board[1][9]
Arrays and Functions • C passes arguments to functions “by value” • A copy of the argument is used in the function • When passing an array by name, a copy of the array’s starting address is passed to the function, not a copy of the array itself • As a result, references to array elements within the function are also references to the array argument.
Array Argument Example void addTwo( int a[], int size ) { int k; for (k = 0; k < size; k++) a[k] += 2; } int main( ) { int j, scores[3]; scores[0] = 42; scores[1] = 33; scores[2] = 99; addTwo( scores, 3); for (j = 0; j < 3; j++) printf(“%d “, scores[j]); /* 44, 35, 101 */ return 0; }
‘o’ ‘b’ \0 ‘b’ name ‘M’ ‘r’ ‘.’ \0 x x x x x x title Strings in C • In C, a string is an array of characters terminated with the “null” character (‘\0’, value = 0). char name[4] = “bob”; char title[10] = “Mr.”;
C String Library • C does provide a library of string functions. Note that assignment( = ) and equality (==) operators don’t do the job. • strlen( char string[ ] ) • Returns the number of characters in the string, not including the “null” character • strcpy( char s1[ ], char s2[ ] ) • Copies s2 on top of s1. The order of the parameters mimics the assignment operator • strcmp ( char s1[ ] , char s2[ ] ) • Returns < 0, 0, > 0 if s1 < s2, s1 == s2 or s1 > s2 lexigraphically • strcat( char s1[ ] , char s2[ ]) • Appends (concatenates) s2 to s1
C String Library (2) • Some function in the C String library have an additional size parameter. • strncpy( char s1[ ], char s2[ ], int n ) • Copies at most n characters of s2 on top of s1. The order of the parameters mimics the assignment operator • strncmp ( char s1[ ] , char s2[ ], int n ) • Compares up to n characters of s1 with s2 • Returns < 0, 0, > 0 if s1 < s2, s1 == s2 or s1 > s2 lexigraphically • strncat( char s1[ ], char s2[ ] , int n) • Appends at most n characters of s2 to s1
String Code char first[10] = “bobby”; char last[15] = “smith”; char name[30]; char you[5] = “bobo”; strcpy( name, first ); strcat( name, last ); printf( “%d, %s\n”, strlen(name) name ); strncpy( name, last, 2 ); printf( “%d, %s\n”, strlen(name) name ); int result = strcmp( you, first ); result = strncmp( you, first, 3 ); strcat( first, last );
“Big Enough” • The “owner” of a string is responsible for allocating array space which is “big enough” to store the string (including the null character) • Most string library functions do not check the size of the string memory.
No Classes in C • Because C is not an OOP language, there is no way to combine data and code into a single entity. C does allow us to combine related data into a single entity known as a struct. All data in a struct can be accessed by any code (like “public” in Java) • The general form of a structure definition is struct tag { member1_declaration; member2_declaration; member3_declaration; . . . memberN_declaration; }; where struct is the keyword, tag names this kind of struct, and member_declarations are variable declarations which define the members. Note the semi-colon
C struct Example • Defining a struct to represent a point in a coordinate plane struct point { int x; /* x-coordinate */ int y; /* y-coordinate */ }; • Given the declarations struct point p1; struct point p2; we access the members of these variables as * the x-coordinate of p1 is p1.x * the y-coordinate of p1 is p1.y * the x-coordinate of p2 is p2.x * the y-coordinate of p2 is p2.y point is the struct tag
Using structs and members • Like other variable types, struct variables (e.g. p1, p2) can be passed to functions as parameters and returned from functions as return types. • The members of a struct are variables just like any other and ca be used wherever any other variable of the same type may be used. For example, the members of the struct point can then be used just like any other integer variables.
printPoint.c #include <stdio.h> void printPoint( struct point point ) { printf (“( %2d, %2d )”, point.x, point.y); } int main ( ) { struct point endpoint; endpoint.x = 12; endpoint.y = 42; printPoint( endpoint ); return 0; }
struct assignment • The contents of a struct variable may be copied to another struct variable of the same type using the assignment (=) operator • After this code is executed struct point p1; struct point p2; p1.x = 42; p1.y = 59; p2 = p1; /* structure assignment copies members */ The values of p2’s members are the same as p1’s members. E.g. p1.x = p2.x = 42 and p1.y = p2.y = 59
struct within a struct • A data element in a struct may be another struct (similar to composition in Java / C++). • This example defines a line in the coordinate plane by specifying its endpoints as POINT structs struct line { struct point leftEndPoint; struct point rightEndPoint; }; • Given the declarations below, how do we access the x- and y-coodinates of each line’s endpoints? struct line line1, line2;
Arrays of struct • Since a struct is a variable type, we can create arrays of structs just like we create arrays of int, char, double, etc. • The declaration struct line lines[42]; creates an array of 42 struct line structures. • Given the declaration above, how do we access the endpoints of the 4th line? How do we access the x-coordinate of each endpoint of the 4th line?
Bitfields • When saving space in memory or a communications message is of paramount importance, we sometimes need to pack lots of information into a small space. We can use struct syntax to define “variables” which are as small as 1 bit in size. These variables are known as “bit fields”. struct weather { unsigned int temperature : 5; unsigned int windSpeed : 6; unsigned int isRaining : 1; unsigned int isSunny : 1; unsigned int isSnowing : 1; };
Using Bitfields struct weather todaysWeather; todaysWeather.temperature = 44; todaysWeather.isSnowing = 0; todaysWeather.windSpeed = 23; /* etc */ if (todaysWeather.isRaining) printf( “%s\n”, “Take your umbrella”); if (todaysWeather.temperature < 32 ) printf( “%s\n”, “Stay home”);
More on Bit fields • Almost everything about bit fields is implementation (machine and compiler) specific. • Bit fields may only defined as (unsigned) ints • Bit fields do not have addresses, so the & operator cannot be applied to them • We’ll see more on this later
Unions • A union is a variable type that may hold different type of members of different sizes, BUT only one type at a time. All members of the union share the same memory. The compiler assigns enough memory for the largest of the member types. • The syntax for defining a union and using its members is the same as the syntax for a struct.
Formal Union Definition • The general form of a union definition is union tag { member1_declaration; member2_declaration; member3_declaration; . . . memberN_declaration; }; where union is the keyword, tag names this kind of union, and member_declarations are variable declarations which define the members. Note that the syntax for defining a union is exactly the same as the syntax for a struct.
union.c union data { int x; char c[8]; } ; int i; union data item; item.x = 42; printf(“%d, %o, %x”, item.x, item.x, item.x ); for (i = 0; i < 8; i++ ) printf(“%x ”, item.c[i]); printf( “%s”, “\n”); printf(“%s\n”, “size of DATA = ”, sizeof(DATA));
Union vs. Struct • Similarities • Definition syntax virtually identical • Member access syntax identical • Differences • Members of a struct each have their own address in memory. • The size of a struct is at least as big as the sum of the sizes of the members (more on this later) • Members of a union share the same memory. The size of a union is the size of the largest member.
typedefs • Defining your own data type names • C provides a facility called typedef for creating new data type names. Use of typedefs can make your code easily changeable and more readable typedef int COORDINATE; typedef int[ 3 ] TABLE;
typedef Example typedef int WIDTH; typedef int LENGTH; typedef double RADIUS; #define PI 3.14159 int rectangleArea( WIDTH width, LENGTH len ) { return width * len; } double circleArea( RADIUS radius ) { return PI * radius * radius; }
Using typedef with a struct • typedef is often used for structs to make coding easier for lazy programmers who can’t type well. In this case the struct tag (point) is not required. typedef int COORDINATE; typedef struct point { COORDINATE x; /* x-coordinate */ COORDINATE y; /* y-coordinate */ } POINT; /* POINT is an alias for this struct */ /* use the alias to declare variables */ POINT p1, p2, endpoint, origin;