Upload
others
View
0
Download
0
Embed Size (px)
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.