const - moodlearn.ariel.ac.il · Compare to Java’s “final” • All (methods as well as data )...

Preview:

Citation preview

1

const

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.

C’s “const”

Examples:

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

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

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

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).

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;

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

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!

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!

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!

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 object obj1 = obj3; // illegal! obj1.setSomeValue(5); // legal!

“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++

int strlen(const char []);

13

C Strings

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.

t x e t Addr. `

`

char* txt1 = "text";

char txt2[] = "text";

char txt3[] =

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

14

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!

15

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!

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 !

t x e t ``

Code part of memory Addr. msg

Stack

OS is protecting this area !

C string literals ("") with const

So, what we do is:

const char* msg = "text";

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

// better!

t x e t ``

Code part of memory Addr. msg

Stack

OS is protecting this area !

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

t x e t ``

Code part of memory Addr. msg

Stack

Stack

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 ("")

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 // segment txt2 = txt1; // legal. now txt2 points to the // same string. txt1 = txt2; // illegal! if (! (strcmp(txt2,"next")) //This condition is now true { ...

21

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);

22

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() …

23

C Strings Functions

An “array” version of strcpy():

void strcpy(char * dest, const char* src) { int i = 0; while ((dest[i] = src[i])!= '\0')) i++; }

24

C Strings Functions

A “pointers” version of strcpy():

void strcpy(char * dest, const char* src) { while ((*dest = *src)!= '\0')) { dest++; src++; } }

25

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++); }

26

How to duplicate a string?

27

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

int main()

{

const char *p1 = "hi mom",

*p2 = (char*)malloc(strlen(p1));

strcpy(p2,p1);

printf("%s\n",p2);

return 0;

}

How to duplicate a string?

28

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

int main()

{

const char *p1 = "hi mom",

*p2 = (char*)malloc(strlen(p1));

strcpy(p2,p1);

printf("%s\n",p2);

return 0;

}

How to duplicate a string?

29

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

int main()

{

const char *p1 = "hi mom",

*p2 = (char*)malloc(strlen(p1)+1);

strcpy(p2,p1);

printf("%s\n",p2);

return 0;

}

strdup: duplicate a string (part of the standard library)

30

char* strdup( char const *p )

{

int n = strlen(p);

char* q =(char*)malloc(sizeof(char)*(n+1));

if( q != NULL )

{

strcpy( q, p );

}

return q;

}

Memory Management

void

foo( char const* p )

{

char *q;

q = strdup( p );

// do something with q

}

The allocated memory remains in use

cannot be reused later on

p

q

<call> …

Heap

‘a’

‘b’

‘\0’

32

Memory Management

void

foo( char const* p )

{

char *q = strdup( p );

// do something with q

free(q);

}

Now the memory is being freed.

Recommended