54
1 Arrays and Strings

1 Arrays and Strings. 2 An array is a collection of variables of the same type that are referred to through a common name. It is a Data Structure which

  • View
    214

  • Download
    0

Embed Size (px)

Citation preview

1

Arrays and Strings

2

• An array is a collection of variables of the same type that are referred to through a common name.

• It is a Data Structure which can hold a set of data items of the same type(e.g., all the exam scores(integers) from test #1.

– In C, all arrays consist of contiguous memory locations. The lowest address corresponds to the first element and the highest address to the last element.

Arrays

3

Single-Dimension Arrays

• General form:

type  array_name[size];

• The amount of storage required:

total bytes = sizeof(type) × size of the array.

4

SIZE - must be positive constant integral expression:

# define max 10

int x[max], y[max*2];

x y 0 0

1 1

9

19

.

.

.

.

.

.

.

.

5

For(i=0;i<=4;i++) a[i] = 7 + i* i;

a 0 7 + 0 * 0 1 7 + 1 * 1 2 7 + 2 * 2 3 7 + 3 * 3 4 7 + 4 * 4

7

11

8

16

23

An element is accessed by subscripting the array name. This is done by placing the subscript of the element within square brackets after the name of the array.

.

.

6

• C has NO subscript checking on arrays.

int count[10], i;

/* this causes count to be overrun */

for(i=0; i<100; i++)  count[i] = i;

Memory will be accessed that has“garbage” values.

7

If you use an invalid subscript in an expression you will get unpredictable results:

Total = count[25] * 24/6 + 9;

There isn’t any count[25] array element that we have initialized. But it will be evaluated into a memory address and will use whatever value is represented in those bytes.

8

On the other hand if you use an invalid subscript in an assignment, you will destroy some undetermined portion of your program. Usually, but not always, your program will continue to run and either produce unpredictable results or abort.

Count[50] = total * taxrate – penalty;

Count[50] is an address that may be withinThe memory allocated for your program.

9

1-D Arrays Initialization• General form

type array_name[size]  = {value_list};

int scores[5] = {60, 40, 90, 80, 60};

scores 0

1 2 3 4

60

908060

40

10

1-D Unsized Array Initializations

• If the size of the array is not explicitly specified, the compiler automatically creates an array big enough to hold all the initializers present. This is called an unsized array.

char e2[] = "Write error\n";printf("%s has length %d\n", e2, sizeof (e2));

Size would be 13 (“\n” 1 char, plus the Null char “/0” 1 char.

11

Variable-Length Arrays

• You can declare an array whose dimensions are specified by any valid expression, including those whose value is known only at run time. This is called a variable-length array.

• Only local arrays. The

Array “str” will be set as

large as the argument passed

to “dim”.

void f(int dim){  char str[dim]; }

12

The fact that an:

Array name is a memory address is Exploited in C.

Since a pointer is a memory address, it follows that an array variable (name) is a pointer, in fact a pointer constant.

Relationship Between Arrays & Pointers

13

• When an array is declared, the compiler must allocate a base address and a sufficient amount of storage to contain all the elements of the array.

Array name Base address

ArrayName [0] Base Address

14

Difference between Pointer and Array Name

• A pointer variable is one that holds an address and can be changed to point to another object of the pointer’s type.

• An Array name is interpreted as the base address of the array which can not be changed. It is a Pointer constant.

15

Array Name as the Address

char a[3];

a[0] a[1] a[2]

addr

ess 1

000

a addr

ess 1

001

addr

ess 1

002

16

int a[5];a[0]=7; a[1]=8; a[2]=11;a[3]=16; a[4]=23;

7 8 11 16 23

addr

ess 1

000

aad

dres

s 100

4

addr

ess 1

008

addr

ess 1

012

addr

ess 1

016

0 1 2 3 4

if int is stored in four bytes.

17

#define n 100

int a[n], *p;

p = a; p = &a[0];

same result

A 0 Both Assign p the

1 the Base Addr of

2 p the Array.

99

.

.

Array Access Thru a Pointer

18

p a 0

1

2

for (p = a; p < &a[n]; ++p)

sum += *p;

Increment Pointer P By 1

p = a; p = &a[0]; Address unit. Pointer

p = a + 1; p = &a[1]; Arithmetic.

p = a + 2; p = &a[2];

.

.

.

19

#include <stdio.h>

Int main(void){ double a[2], *p, *q;

p = &a[0];

q = p+1; // or q=&a[1];

printf(“%dn\”, q-p); //1 is printed printf(“%d\n”, (int)q-(int)p); //8 is printed

return 0;}

Page 311

q-p yields the int value representing the number of array elements between q and p.

this is system dependent

20

Note: Because an Array name e.g., a is a constant pointer & not a variable, we can’t change the Addr

of a.

a = p; ++a; a + = 2;

ILLEGAL

21

Passing 1-D Arrays To Functions

When an Array is Being passed its Base Address (array’s name without an index) is passed.

The Array elements themselves are not copied.

We are implementing ?

Call by Valueor

Call by Reference.

22

int sum (int a[ ],int a[ ], int n)

{

Sums Arrays elements

& returns Sum

}

a[ ] is actually a pointer. We are allowed use of [ ] to remind us it is an Array Address being passed in.

23

How to invoke the previous function.

Function Calls : (Base Addr, # of elements being summed).

sum(a, n)

Suppose V V is an Array of SIZE 100 which exists & is Loaded.

sum (v, 100)sum (v + 4, 50) v[4]…v[53]sum (&v[9], 60) v[9]…v[68]

How could you write the Formal parameter receivingAn array in a different manner?

24

int main(void){  int i[10];   func1(i);   /* . . . */}

void func1(int *x)  /* pointerpointer */{   /* . . . */}

void func1(int x[10]) /* sized arraysized array */{  /* . . . */}

void func1 (int x[]) /* unsized arrayunsized array */{  /* . . . */}

25

Two-Dimensional Arrays• A two-dimensional array is an array of one-

dimensional arrays.

int d[10][20];

• The number of bytes of memory needed to hold it:

Four bytes integer: 10 × 20 ×4= 800 Bytes.

26

• They are stored in a row-column matrix.

left index row

right index column.

• This means that the right index changes faster than the left when accessing the elements in the array in the order in which they are actually stored in memory.

27

ch[0][0] ch[0][1] ch[0][2]

char ch[4][3];

ch[1][0] ch[1][1] ch[1][2]

ch[2][0] ch[2][1] ch[2][2]

ch[3][0] ch[3][1] ch[3][2]

Right index determines column.

Left index deter-mines row

28

2-D Arrays Initializationint sqrs[10] [2] = {  1, 1,  2, 4,  3, 9,  4, 16,  5, 25,  6, 36,  7, 49,  8, 64,  9, 81,  10, 100};

int sqrs[10] [2] = {  {1, 1},  {2, 4},  {3, 9},  {4, 16},  {5, 25},  {6, 36},  {7, 49},  {8, 64},  {9, 81},  {10, 100}};

subaggregate grouping

29

2-D Unsized Array Initializationsint sqrs[] [2] = {  {1, 1},  {2, 4},  {3, 9},  {4, 16},  {5, 25},  {6, 36},  {7, 49},  {8, 64},  {9, 81},  {10, 100}};

int sqrs[] [2] = {  1, 1,  2, 4,  3, 9,  4, 16,  5, 25,  6, 36,  7, 49,  8, 64,  9, 81,  10, 100};

30

Passing 2-D Arrays To Functions• When a two-dimensional array is used as

an argument to a function, only a pointer to the first element is actually passed.

• However, the parameter receiving a two-dimensional array must define at least the size of the rightmost dimension.

void func1(int x[] [2] [2])){  /* . . . */}

31

#include <stdio.h>int main(void){  int t, i, num[3][4];   for(t=0; t<3; ++t)    for(i=0; i<4; ++i)      num[t][i] = (t*4)+i+1;  

/* now print them out */  for(t=0; t<3; ++t) {    for(i=0; i<4; ++i)      printf(''%3d ", num[t] [i]);    printf("\n");  }  return 0;}

1 2 3 4

5 6 7 8

9 10 11 12

012

0 1 2 3

num[t][i]

Nested loop.Why?

32

Mapping How an Array Address is Pg. 316

created.

aa 0 1 2 3 4

0

1

2

a[i][j] *(&a [0] [0] + 5 * i + j)

a[2] [4] 0 + 5 * 2 + 4 The Row

a + 14

0 1 2 3 4

5 6 7 8 9

10 11 12 13 14 # of column

33

Multi-Dimensional Arrays• General form:

type name[Size1][Size2][Size3] . . .[Sizen];

• The number of bytes of memory needed to hold it:

bytes = size of 1st index × 

size of 2nd index × …. ×

size of nth index

sizeof(base type)

34

The first dimension is called the ‘Plane” of the array.

int c [3] [5] [10] - 3 – dimensions 2

1

C 0 1 2 3 4 5 6 7 8 9 01234 0

35

Passing M-D Arrays To Functions

• When passing multidimensional arrays into functions, you must declare all but the leftmost dimension.

int m[4][3][6][5];

void func1(int d[][3][6][5]){  /*  . . . */}

36

Memory AllocationMemory Allocation• Dynamic Memory Allocation: Uses

predefined functions to allocate and release memory for data while the program is running.

• Static Memory Allocation: Memory whose allocation is determined by the compiler and therefore preset before run time. Uses definitions and declarations in the source code. The number of bytes reserved can not be changed at run time.

37

Heap• Memory allocated by C's dynamic allocation

functions is obtained from the heap.

• The heap is free memory that is not used by your program, the operating system, or any other program running in the computer.

• The size of the heap cannot usually be known in advance, but it a typically contains a fairly large amount of free space.

• Although the size of the heap is often quite large, it is finite and can be exhausted.

38

Dynamic Allocation Functions• calloc malloc

• Function prototypes:void * calloc(n, object_size)void * malloc(n * object_size)

• They are declared in the header <stdlib.h>.

• Return type void *: Can be assigned to any type of pointer without casting.

39

Dynamic Allocation Functions (cont.)

• Returns a pointer to enough space in memory to store n objects each of size bytes. N and size should be positive integers.

• If the system is unable to allocate the

requested memory, the pointer value NULL is returned.

40

p = calloc (n, sizeof(int));

10

p

100 102 104 106 108 110 112 114 116 118

int 2 Bytes

Calloc is primarily used to allocate memory for arrays.

100

41

Dynamic Allocation Functions (cont.)

• Difference:– The storage set aside by calloc is

automatically initialized to zero(blank if char).

– The storage set aside by malloc is not initialized and therefore start with a garbage value.

• If efficiency is an issue, programmers prefer malloc instead of calloc.

42

Examples

char *p;p = malloc(1000);  /* get 1000 bytes */

/*p points to the first of 1,000 bytes of memory */

int *p;/* allocates space for 50 integers */ p = malloc(50*sizeof(int));

p = malloc(100);if(!p) {  printf(''Out of memory.\n");  exit (1);}

43

Releasing Allocated Memory Function

• Space is NOT released on function exit.

free

• It is declared in the header <stdlib.h>.

• It returns previously allocated memory to the system.

• Function prototype: void free(void *p);

e.g. free(p);

44

StringsStrings

45

String

• The most common array is the string, which is simply an one-dimensional array of characters terminated by a null.

• The End-of-String Sentinel (delimiter) \0. #define MAXWORD 100

int main(void){

char w[MAXWORD];char w[MAXWORD];w[0] = ‘A’;w[1] = ‘\0’;/*….*/

46

• When declaring a character array that will hold a string, you need to declare it to be one character longer than the largest string that it will hold.

• WHY?

//to declare an array str that can hold a //10 characters string

char str[11];

47

String Initialization• General form:

char array_name[size]  =  “string”;

char str[9] = “I like C”;

char str[9] = {'I', ' ', 'l', 'i', 'k', 'e',' ', 'C', '\0'};

char *p = “I like C”;

48

• The format %s is used for a string.scanf(“%s”, w); //if w is a string

varprintf(“%s”, w);

• ‘a’ and “a” are very different.

‘a’ a character constant“a” a array of characters with

two elements.

49

String-Handling Functions• Standard header <string.h> Pg. 349

strcpy(s1, s2) Copies s2 into s1

strcat(s1, s2) Concatenates s2 onto the end

of s1.

strlen(s1) Returns the length of s1

strcmp(s1, s2) Returns 0 if s1 and s2 are the

same; less than 0 if s1<s2;

greater than 0 if s1>s2

50

strchr(s1, ch) Returns a pointer to

the first occurrence of

ch in s1.

strstr(s1, s2) Returns a pointer to

the first occurrence of

s2 in s1.

51

#include <stdio.h>#include <string.h>int main(void){  char s1[80], s2[80];   gets(s1); gets(s2);

  printf("lengths: %d %d\n", strlen(s1),  strlen(s2));  

if(!strcmp(s1, s2)) printf("The strings are equal\n");  

HelloHellolengths: 5 5The strings are equal

52

strcat(s1, s2); hellohello

printf (''%s\n", s1); This is a test

e is in hello

found hi   

strcpy(s1, "This is a test.\n"); printf(s1);

 if(strchr("hello", 'e')) printf("e is in hello\n"); if(strstr("hi there", "hi")) printf("found hi");  

return 0;}

53

Dynamically Allocated Strings

• The type pointer to char is conceptually a string.

• An example follows:

54

/* Allocate space for a string dynamically, request user   input, and then print the string backwards. */#include <stdlib.h>#include <stdio.h>#include <string.h>int main(void){  char *s;  int t;   s = malloc(80);   if(!s) {    printf(''Memory request failed.\n");    exit (1);  }   gets(s);  for(t=strlen(s)-2;  t>=0; t--)  putchar(s[t]);  free(s);  return 0;}