Top Banner
1 Memory, Arrays & Pointers
70

Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Jun 19, 2018

Download

Documents

doankien
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

1

Memory, Arrays & Pointers

Page 2: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Memory

2

int main()

{

char c;

int i,j;

double x;

c i j x

Page 3: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Arrays

Defines a block of consecutive cells

int main()

{

int i;

int a[3];

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

Page 4: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Arrays - the [ ] operator

4

int arr[5] = { 1, 5, 2, 1 ,3 }; /*arr begins at

address 40*/

Address Computation Examples:

1. arr[0] 40+0*sizeof(int) = 40

2. arr[3] 40+3*sizeof(int) = 52

3. arr[i] 40+i*sizeof(int) = 40 + 4*i

4. arr[-1] 40+(-1)*sizeof (int) = 36 // can be the code

// segment or other variables

1 5 2 1 3

40 44 48 52 56 60

Page 5: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Arrays

5

C does not provide any run time checks

int a[4];

a[-1] = 0;

a[4] = 0;

This will compile and run (no errors?!)

…but can lead to unpredictable results.

It is the programmer’s responsibility to check whether the index is out of bounds…

Page 6: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Arrays

C does not provide array operations:

int a[4]; int b[4];

a = b; // illegal if( a == b ) // legal. ==0, address comparison.

6

Page 7: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Arrays

a[i] is just translated to (*(a+i)), thus this

code will compile and run fine

int a[4];

0[a]= 42;// first element of array is 42

1[a]= -1;// second element of array is -1

7

Page 8: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Array Initialization

8

// Works, but IMHO in some cases, bad style

int arr[3] = {3, 4, 5};

// Good (robust to changes)

int arr[] = {3, 4, 5};

// Bad style - Init all items to 0 takes O(n)

int arr[3] = {0};

// Bad style - The last is 0

int arr[4] = {3, 4, 5};

Page 9: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Array Initialization

9

// Does not compile

int arr[2] = {3, 4, 5};

// Does not compile - array assignment

// only in initialization

int arr[3];

arr = {2,5,7};

Page 10: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Array Initialization – multidimensional

(more on this later)

10

// Good, works same as arr[2][3]

int arr[][3] = {{2,5,7},{4,6,7}};

// Bad style, but same as above

int arr[2][3] = {2,5,7,4,6,7};

// Does not compile

int arr[3][2] = {{2,5,7},{4,6,7}};

Page 11: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Pointers

Data type for addresses

(almost) all you need to know is:

& *

Page 12: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Pointers

• Declaration

<type> *p; <type>* p;

Both, p points to objects of type <type>

• Pointer value

*p = x;

y = *p;

*p refers to the object p points to

• Value pointer

&x - the pointer to x(x’s address)

12

Page 13: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Pointers - 64 bit!

int main() {

int i,j; int *x; // x points to an integer i = 1; x = &i; j = *x; x = &j; (*x) = 3;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

i j x

0 1 2 3 4 5 7 8 9 10 11 12 13 14 15 16 17 186

13

Page 14: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Pointers - 64 bit!

int main() {

int i,j; int *x; // x points to an integer i = 1; x = &i; j = *x; x = &j; (*x) = 3;

1 0 0 0 ? ? ? ? ? ? ? ? ? ? ? ?

i j x

0 1 2 3 4 5 7 8 9 10 11 12 13 14 15 16 17 186

14

Page 15: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Pointers - 64 bit!

int main() {

int i,j; int *x; // x points to an integer i = 1; x = &i; j = *x; x = &j; (*x) = 3;

1 0 0 0 ? ? ? ? ? ? ? ? ? ? ? ?

i j x

0 1 2 3 4 5 7 8 9 10 11 12 13 14 15 16 17 186

15

Little Endian

Page 16: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Pointers - 64 bit!

int main() {

int i,j; int *x; // x points to an integer i = 1; x = &i; j = *x; x = &j; (*x) = 3;

1 0 0 0 ? ? ? ? 0 0 0 0 0 0 0 0

i j x

0 1 2 3 4 5 7 8 9 10 11 12 13 14 15 16 17 186

16

Page 17: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Pointers - 64 bit!

int main() {

int i,j; int *x; // x points to an integer i = 1; x = &i; j = *x; x = &j; (*x) = 3;

1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0

i j x

0 1 2 3 4 5 7 8 9 10 11 12 13 14 15 16 17 186

17

Page 18: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Pointers - 64 bit!

int main() {

int i,j; int *x; // x points to an integer i = 1; x = &i; j = *x; x = &j; (*x) = 3;

1 0 0 0 1 0 0 0 4 0 0 0 0 0 0 0

i j x

0 1 2 3 4 5 7 8 9 10 11 12 13 14 15 16 17 186

18

Page 19: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Pointers - 64 bit!

int main() {

int i,j; int *x; // x points to an integer i = 1; x = &i; j = *x; x = &j; (*x) = 3;

1 0 0 0 3 0 0 0 4 0 0 0 0 0 0 0

i j x

0 1 2 3 4 5 7 8 9 10 11 12 13 14 15 16 17 186

19

Page 20: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Example – the swap function

Does nothing Works

20

void swap(int a, int b) {

int temp = a; a = b; b = temp;

} int main() {

int x, y; x = 3; y = 7; swap(x, y); // now x==3, y==7

void swap(int *pa, int *pb) {

int temp = *pa; *pa = *pb; *pb = temp;

} int main() {

int x, y; x = 3; y = 7; swap(&x, &y); // x == 7, y == 3

Page 21: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

8 0 0 0 0 0 0 0 1 0 0 0

Pointers & Arrays

21

int *p;

int a[3];

p = &a[0]; // same as p = a

*(p+1) = 1; // assignment to a[1]!

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

Page 22: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Pointers & Arrays

22

Arrays are can sometimes be treated as address of the first member.

int *p;

int a[4];

p = a; // same as p = &a[0];

p[1] = 102; // same as *(p+1)=102;

*(a+1) = 102; // same as prev. line

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

a = p; // illegal

a++; // illegal

Page 23: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Pointers & Arrays

23

But:

int *p;

int a[4];

sizeof (p) == sizeof (void*)

sizeof (a) == 4 * sizeof (int)

Size of the array is known in

compile time

Page 24: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Pointers & Arrays

24

int main()

{

int arr[] = {1,3,5,4};

int sum = 0;

size_t i;

for (i=0; i<sizeof(arr)/sizeof(arr[0]); ++i)

{

sum += arr[i];

}

}

Page 25: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

size_t

25

Page 26: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

size_t

26

an unsigned data type, defined in stddef.h

It can be imported by inclusion of stdlib.h (as this file

includes stddef.h)

This type is used to represent the size of an object. Library

functions that take or return sizes expect them to be of type or

have the return type of size_t

The most frequently used compiler-based operator sizeof

should evaluate to a constant value that is compatible with

size_t

Page 27: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

size_t

27

size_t is a type guaranteed to hold any array index.

Use size_t indices and not int. Why?

1. Because it tells the story better

2. Because the C standard uses it (you will get warnings

against int)

3. Because int range might be too small for large arrays

Danger: You cannot test that a variable of an unsigned type is

smaller than 0, because it never happens!

Page 28: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

size_t

28

Danger: You cannot test that a variable of an unsigned type is

smaller than 0, because it never happens!

Instead make sure that it doen’t happen

For example: use the “arrow operator”:

for (size_t i=ARR_SIZE-1; i-- > 0;) {

arr[i] = ...;

Page 29: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

ptrdiff_t

29

ptrdiff_t is the signed integer type of the result of

subtracting two pointers

More info:

http://en.cppreference.com/w/c/types/ptrdiff_t

Page 30: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Pointers & Arrays

30

Page 31: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Pointers & Arrays

int foo( int *p );

and

int foo( int a[] );

Are declaring the same interface.

In both cases, a pointer to int is

being passed to the function foo

31

Page 32: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Pointers & Arrays

int foo( int *p );

and

int foo( int a[3] );

Are declaring the same interface.

In both cases, a pointer to int is

being passed to the function foo

32

Page 33: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Pointers & Arrays

33

int sum (int arr[])

{

size_t i;

int sum = 0;

for (i=0; i<sizeof(arr)/sizeof(arr[0]); ++i)

{

sum += arr[i];

}

return sum;

}

// error: sizeof (arr) = sizeof (void*)

int* ≡ arr[] !≡ arr[N]

Page 34: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Pointers & Arrays

34

int sum (int arr[42])

{

size_t i;

int sum = 0;

for (i=0; i<sizeof(arr)/sizeof(arr[0]); ++i)

{

sum += arr[i];

}

return sum;

}

// error: sizeof (arr) = sizeof (void*)

int* ≡ arr[] !≡ arr[N]

Page 35: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Pointers & Arrays

35

int sum (int arr[], size_t n)

{

size_t i;

int sum = 0;

for (i=0; i<n; ++i)

{

sum += arr[i]; // = arr+ i*sizeof(int)

}

return sum;

}

Array size must be passed as a parameter

Page 36: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Pointer Arithmetic

int a[3];

int *p = a;

char *q = (char *)a; // Explicit cast

// p and q point to the same location

p++; // increment p by 1 int (4 bytes)

q++; // increment q by 1 char (1 byte)

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

q P

36

Page 37: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Pointer Arithmetic

37

int FindFirstNonZero( int a[], size_t n )

{

int *p= a;

while( (p<a+n) && ((*p) == 0) ) ++p;

return p-a;

}

Same as

int FindFirstNonZero( int a[], size_t n )

{

int i= 0;

while( (i<n) && (a[i] == 0) ) ++i;

return i;

}

Pre

fera

ble

Page 38: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Pointer Arithmetic

38

int a[4];

int *p= a;

long i= (long)a;

long j= (long)(a+1); // add 1*sizeof(int)

to a;

long dif= (long)(j-i); // dif= sizeof(int)

Be careful: Pointer arithmetic works just with

pointers

Page 39: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

void *

39

void* p defines a pointer to

undetermined type

int j;

int* p= &j;

void* q= p; // no cast needed

p = (int*)q ; // cast is needed

Page 40: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

void *

40

void* address jumps in bytes (like char*)

We cannot access to the content of the

pointer

int j;

void *p = &j;

int k = *p; // illegal

int k = (int)*p ; // still illegal

int k = *(int*)p; // legal

Page 41: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

NULL pointer

41

Special value: points to “nothing” (defined in stdlib.h, usually as 0 of type void*):int *p = NULL;

if( p != NULL )

{

}

Page 42: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

NULL pointer

42

int *p = NULL;

*p = 1;

Will compile…

… but will lead to runtime error

Page 43: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Pointers to pointers

43

Pointer is a variable type, it also has an address:

int main()

{

int n = 17;

int *p = &n;

int **p2 = &p;

printf("the address of p2 is %p \n",&p2);

printf("the address of p is %p \n",p2);

printf("the address of n is %p \n",*p2);

printf("the value of n is %d \n",**p2);

return 0;

}

Page 44: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

44

const

Page 45: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

C’s “const”

C’s “const” is a qualifier that can be applied to the

declaration of any variable to specify its value will

not be changed.

Page 46: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

C’s “const”

Examples:

const double E = 2.71828; E= 3.14; // compile error!

const int arr[] = {1,2}; arr[0] = 1; // compile error!

Page 47: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

C’s “const”

• C’s “const” can be cast away

• Helps to find errors.

• Doesn't protect from evil changes !

const int arr[] = {1,2};

int* arr_ptr = (int*)arr;

arr_ptr[0] = 3; // compile ok!

// but might give a run-time error

Page 48: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Const and Pointer’s Syntax

Const protects his left side, unless there is

nothing to his left and only then it protects his

right side (examples next slide).

Page 49: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Const and Pointer’s Syntax

// Both, cannot change the int pointed by p

// using p

const int * p = arr;

int const * p = arr;

// Cannot change the address stored in p

int * const p = arr;

// Cannot change the address stored in p

// and the int pointed by p using p

int const * const p = arr;

Page 50: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Const and Pointer’s Syntax

// Both, cannot change the int pointed by p

// using p

const int * p = arr;

int const * p = arr;

// Cannot change the address stored in p

int * const p = arr;

// Cannot change the address stored in p

// and the int pointed by p using p

int const * const p = arr;

Very Useful

Never saw it

being used

Page 51: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

C’s “const”

Do not confuse what the “const” declaration “protects”!

A pointer to a const variable:

A const pointer to a variable:

ptr value``

ptr value``

int arr[] = {1,2,3};

int const * p = arr;

p[1] = 1; // illegal!

*(p+1) = 1; // illegal!

p = NULL; // legal

int arr[] = {1,2,3};

int* const const_p = arr;

const_p[1] = 0; // legal!

const_p = NULL; // illegal!

Page 52: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

C’s “const”

How about arr itself?

int arr[] = {1,2,3};

int* const const_p = arr;

const_p[1] = 0; // legal!

const_p = NULL; // illegal!

int *p;arr=p; // compile error!

Page 53: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Const and User Defined Types

All the members of a const variable are immutable!

typedef struct Complex

{

int _real, _img;

int *_imgP;

} Complex;

Complex const COMP1 = comp2; // ok, init. using comp2

Complex const COMP3 = {3,2,&someInt}; // ok, copying values

COMP1._img = 3; // illegal!

COMP3._imgP = &someOtherInt; // illegal!

*(COMP3._imgP) = 5; // legal!

Page 54: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Compare to Java’s “final”

• All (methods as well as data ) are Class members.

• “final” makes primitive types constants and

references to objects constant.

• The values inside the referred final objects are not

necessarily constant !

final int LIMIT = 10; LIMIT = 11; // illegal!

final MyObject obj1 = new MyObject(); MyObject obj2 = null; MyObject obj3 = new MyObject(); obj2 = obj1; // fine, both point now to the same objectobj1 = obj3; // illegal! obj1.setSomeValue(5); // legal!

Page 55: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

“Const” Usage

The const declaration can (and should!) be used in the definition of a function’s arguments, to indicate it would not change them:

Why use? (This is not a recommendation but a must) clearer code

avoids errors

part of the interfaces you define!

can be used with const objects

More of “const” meaning and usage in C++

size_t strlen(const char []);

Page 56: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

C strings manipulation

56

#include <string.h>

strcmpstrcpystrlen…http://www.cplusplus.com/reference/cstring/

Page 57: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

57

C Strings

Page 58: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Strings

Java:

Char: is 2 bytes (Unicode)

String: an object which behaves as a primitive type (an

immutable object, passed by value)

C:

char: usually 1 byte. An Integer.

string: an array of characters.

txetAddr.`

`

char* txt1 = "text";

char txt2[] = "text";

char txt3[] =

{’t’,’e’,’x’,’t’,’\0’};

58

Page 59: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

C Strings

Strings are always terminated by a null character, (a

character with integer value 0).

There is no way to enforce it automatically when you

create your own strings, so:

remember it’s there

allocate memory for it

specify it when you initialize char by char

char* text = "string";

// means text[5] = g and text[6] = \0

// 7 chars are allocated!

59

Page 60: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

C string literals ("")

When working with char*, C string literals ("") are written

in the code segment (part) of the memory.

Thus, you can't change them!

Page 61: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

C string literals ("")

When working with char*, C string literals ("") are written

in the code segment (part) of the memory.

Thus, you can't change them!

char* msg = "text";

msg[0] = ‘w’; // seg fault! – error caught only in runtime !

txet``

Code part of memory

Addr.msg

Stack

OS is protecting this area !

Page 62: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

C string literals ("") with const

So, what we do is:

const char* msg = "text";

msg[0] = ‘t’; // compile error!

// better!

txet``

Code part of memory

Addr.msg

Stack

OS is protecting this area !

Page 63: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

Difference between initialzing a pointer

and an array with C string literals ("")

char* msg = "text";// msg is a pointer that points to a memory that is in the code part

char msg2[] = "text";// msg2 is an array of chars that are on the stack

t

e

x

t

\0

txet``

Code part of memory

Addr.msg

Stack

Stack

Page 64: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

char* msg = "text"; msg[0]= 'n'; // seg fault - trying to change

what is written in the code part of the memory

char msg2[] = "text";msg2[0]= 'n'; // ok - changing what is written

in the stack part of the memory

Difference between initialzing a pointer

and an array with C string literals ("")

Page 65: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

C Strings Examples

char txt1[] = "text";char* txt2 = "text";

int i = strlen(txt1); // i = 4, same for strlen(txt2)

txt1[0] = ’n’; // now txt1="next“*txt2 = ’n’; // illegal! “text” is in the code

// segmenttxt2 = txt1; // legal. now txt2 points to the

// same string.txt1 = txt2; // illegal!

if (! (strcmp(txt2,"next")) //This condition is now true{

...

65

Page 66: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

C Strings Manipulation

To manipulate a single character use the functions

defined in ctype.h

Manipulation of Strings is done by including the string.h

header file

#include <ctype.h>

char c = ‘A’;

isalpha(c); isupper(c); islower(c); …

// copy a string

char* strcpy(char * dest, const char* src);

// append a string

char* strcat(char * dest, const char* src);

66

Page 67: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

C Strings Manipulation (2)

NOTE : All C library functions assumes the usages of ‘\0’ and enough

storage space. No boundary checks! You are responsible. http://www.cplusplus.com/reference/cstring/

// compare two strings. // when str1 < str2 lexicographically return < 0 // when str1 > str2 lexicographically return > 0 // when identical return 0 int strcmp(const char * str1, const char* str2);

// return strings length, not including the \0!! size_t strlen(const char * str);

// Other functions: strncpy(),strncat(),strncmp() …

67

Page 68: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

C Strings Functions

An “array” version of strcpy():

void strcpy(char * dest, const char* src) {

size_t i = 0; while ((dest[i] = src[i])!= '\0')) i++;

}

68

Page 69: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

C Strings Functions

A “pointers” version of strcpy():

void strcpy(char * dest, const char* src) {

while ((*dest = *src)!= '\0')) {

dest++;src++;

} }

69

Page 70: Memory, Arrays & Pointers foo( int *p ); and int foo( int a[] ); Are declaring the same interface. In both cases, a pointer to int is being passed to the function foo 31 Pointers &

C Strings Functions (2)

A shorter version::

Actually the comparison against \0 is redundant:

Style note: Unlike K&R book, we do NOT encourage

you to write such code. However, you should be able to

read and understand it.

void strcpy(char * dest,const char* src) {

while ((*dest++ = *src++)!= '\0')); }

void strcpy(char * dest,const char* src) {

while (*dest++ = *src++);}

70