C Language Strings Flashcards
Why can / should we not edit pointer to a string literal
Has undefined results
○ On some compilers (e.g. LCC), it works!
○ On other compilers, the data in the array is treated as read-only or “constant.”
Character array vs. string vs. pointer to the string
○ String
■ char my_string [ ] = {‘T’, ‘o’, ‘m’, ‘\0’} ;
○ Pointer to string
■ char* my_string_ptr = “Tom” ;
■ You cannot edit a pointer to a string literal!
○ Array contains a string
■ char my_string [ ] = “Tom” ;
■ You are allowed to edit a character array.
Array of Strings / 2D Array
■ char my_2D_array [3][4] = { {‘I’, ‘\0’},{‘a’, ‘m’, ‘\0’},{‘T’, ‘o’, ‘m’,‘\0’} } ;
○ This is just a 2D array of characters in C (notice no NULLs): char my_2D_array [3][4] = { {‘I’}, {‘a’, ‘m’}, {‘T’, ‘o’, ‘m’} } ;
Passing a 2D array in C
○ Note: absence of row number is permissible in 2D array declaration, but absence of column number is not permissible in 2D array declaration.
○ In reality, our function is receiving a memory address. Dereferencing with [ ] is automated pointer arithmetic. By providing the # of columns in the 2D
array, we are telling the compiler how many rows in memory to advance each time the pointer is referenced using the first [ ] operator.
strlen()
only counts characters up to (but not including) the first ‘\0’ although space is allocated as asked for.
Arrays of pointers
○ Integer pointer: int var[ ] = {10, 100, 200}; int i, *ptr[MAX]; for ( i = 0; i < MAX; i++) { ptr[i] = &var[i]; /* assign the address of integer. */ } ○ String Pointer: char *names[ ] = { "Zara Ali", "Hina Ali", "Nuha Ali", "Sara Ali" };
Common use of pointers to pointers
Pointers to pointers: often used in C to receive addresses of arrays of pointers to strings
○ int a = 1;
○ int * a_ptr = &a;
○ int ** a_ptr_ptr = &a_ptr;
○ Dereferencing
char I_array [] = {‘I’, ‘\0’ } ;
char Am_array [] = {‘a’, ‘m’, ‘\0’ } ;
char Tom_Array [] = {‘T’, ‘o’, ‘m’, ‘\0’ } ;
char* array_of_ptrs [3] = { I_array, Am_array, Tom_Array } ;
char** ptr_to_ptr = array_of_ptrs ;
○ ptr_to_ptr[0] => I_array
○ ptr_to_ptr[0][0] => ‘I’
○ Recall the two strings that we can use inside main( ) via argv[ ].
Is this structure valid
char *names[]={“anna”,”bob”}
Yes it is an array of strings.
To access ‘a’ in ‘anna’ -> names[0][0]
Pointer to Array of Strings, i.e. Pointer to array of pointers
char *ptr[3] = {"I","am","XYZ"}; char **ptrptr = ptr; printf("%s\n", *ptrptr); ptrptr++; printf("%s\n", *ptrptr);
prints out:
I
am
char *text = “hello”;
vs
char text[] = “hello”
First one, called string literal. Immutable stored in read only memory.
–> Pointer to a string
Second one mutable.
-> array that contains a string
char *text[] = {“hello”, “world”};
vs
char text[2][6] = {“hello”, “world”};
- Array of two pointers to string literals. string literals immutable
- 2D Array containing 2 strings
- char text[2][6] = {“hello”, “world”};
- char text[][6] = {“hello”, “world”};
- char text[][] = {“hello”, “world”};
I can skip row index but NOT column index. i.e. 1 ad 2 work 3 not.
Reason, compiler needs to know how many lines to jump over before storing next string
Where are string literals placed
C compiler can place it anywhere it likes.
It may be stored in static memory
It may be in the OBJECT file itself (like immediate data)
What happens if you try to edit point to string literal
Undefined results
On some compilers it works, On other compileres, the data in the array is treated as read-only or constant
strlen
size_t strlen(const char *str) This function returns the length of string
How to include standard library
include
Can we do pointer arithmetic with an array
if it is a pointer to an array yes.
If it is the array label no. Not really a variable, just a sticker that cannot be moved
Array of Strings? 1D or 2D?
2D Array
interpretation of: char (*ptr)[10]
pointer that can point to an array of 10 characters.
() required as otherwise [] would have priority
When you dereference this pointer you get an array back with 10 entries.
If increment i.e. ptr[0] to ptr[1] you jump over 10 buckets
char text[2][6] = {“hello”, “world”};
copy(text);
what is passed for text on the stack when copy is called
text will hold the address of the first element of the text array
pointer that can point to whole array instead of only one element of the array
int main() { // Pointer to an integer int *p;
// Pointer to an array of 5 integers int (*ptr)[5]; int arr[5];
// Points to 0th element of the arr. p = arr;
// Points to the whole array arr. ptr = &arr;
printf("p = %p, ptr = %p\n", p, ptr); p++; ptr++; printf("p = %p, ptr = %p\n", p, ptr); return 0; }
p = 0x7fff4f32fd50, ptr = 0x7fff4f32fd50 p = 0x7fff4f32fd54, ptr = 0x7fff4f32fd64
p: is pointer to 0th element of the array arr, while ptr is a pointer that points to the whole array arr.
The base type of p is int while base type of ptr is ‘an array of 5 integers’.
We know that the pointer arithmetic is performed relative to the base size, so if we write ptr++, then the pointer ptr will be shifted forward by 20 bytes.
char* text[] = {“hello”, “world”};
This is an array of pointers to strings.
Advantage it does not waste the extra space in memory.
every string only takes up as much space it needs and not as for Array of Strings, where every string used as much space as the largest element in the array .
Pointer to Array of pointers to strings
char* text[] = {“hello”, “world”};
char** ptr_to_ptr = text; // text holds a pointer to the first string. hence double pointer
Wenn ich tuerchenn an der addresse oeffne fuer welche text steht. Was bekomme ich? Pointer? d.h. ich habe ein pointer to pointer.
Equivalent form for char** argv
char* argv[]
char array [][4]
vs.
char** array OR char* array[]
array of strings
vs.
array of pointers to strings. not the same
strcat
char *strcat(char *dest, const char *src)
dest − This is pointer to the destination array, which should contain a C string, and should be large enough to contain the concatenated resulting string.
src − This is the string to be appended. This should not overlap the destination.
This function returns a pointer to the resulting string dest.
strcmp
int strcmp(const char *str1, const char *str2) str1 − This is the first string to be compared.
str2 − This is the second string to be compared.
if Return value < 0 then it indicates str1 is less than str2.
if Return value > 0 then it indicates str2 is less than str1.
if Return value = 0 then it indicates str1 is equal to str2.
strtol
long int strtol(const char *str, char **endptr, int base)
str − This is the string containing the representation of an integral number.
endptr − This is the reference to an object of type char*, whose value is set by the function to the next character in str after the numerical value.
base − This is the base, which must be between 2 and 36 inclusive, or be the special value 0.
This function returns the converted integral number as a long int value, else zero value is returned.
strchr
char *strrchr(const char *str, int c)
str − This is the C string.
c − This is the character to be located. It is passed as its int promotion, but it is internally converted back to char.
This function returns a pointer to the first occurrence of character in str. If the value is not found, the function returns a null pointer.
strcpy
char *strcpy(char *dest, const char *src)
dest − This is the pointer to the destination array where the content is to be copied.
src − This is the string to be copied.
This returns a pointer to the destination string dest.
What is this
char* f[3] = { “I”, “am”, “Tom” } ;
a 3-element array of char* pointers
int a[10] = {0} ;
The above assignment initializes each of the 10 elements of the array (a) to 0?
Alternative way?
False, it only initializes the first element to 0.
e.g. int a[3] = {5}
yields a[3]={5,0,0};
how to fix, use memset(a,0,sizeof(int)*3)
char* c[3] = { “I”, “am”, “Tom” } ;
c[0][0] = ‘U’ ;
Does this work?
No c is an array of pointers to string literals. string literals cannot be edited.
Instantiating pointer to pointer and pointer to 2D String array
char my_2D_Array[][4] ={“abc”,”def”}; //Array of Strings
char (* ptr)[4] = my_2D_Array; // char *ptr = my_2D_Array; does not work as it is 2D Array
char *ptr_array[] ={“ghi”,”jkl”}; //Array of pointers to STrings
char **ptr_ptr = ptr_array; //Pointer to first Pointer in Array of Pointers