MESSAGE
DATE | 2010-03-03 |
FROM | Ruben Safir
|
SUBJECT | Re: [NYLXS - HANGOUT] C++ Workshop _ Syntax Basics - agregate data
|
On Wed, Mar 03, 2010 at 11:24:33PM -0500, Ruben Safir wrote: > > A particularly special array is the charater array, which in C forms the > basis for strings. We already know that a single char is a C and C++ > built in data type and we can have an array of chars, and lastly that we > can have string literals, which are constant. For review, lets look at > code examples of each: > > Example A: > char car = 'A'; //a single character assigned to a char variable. Note > //the single quote > Example B: > char cararray[] = {'A', 'B', 'C', 'D'}; // The definition and assignment > An array of 4 chars, > //which got it's size with the > //initialization of the array > //and of which each of which > //element can be accessed > //through indexing ie: > //char b = cararray[3] or > //pointers such as > //char b = *(cararray + 3) > > Example C: > const char *stringo = "ABCD"; //This is the assignment of a string > //constant literal to a pointer to a > //char constant. This is a real string > //that differs from the above example > //because it creates an array of chars, > //not 4 chars long but 5 chars long > //because it appends a NULL character > //to the end > > > Example D: > char[] = "My Dog Has Fleas\n";//similar to above with 19 char > //assigned to the array ending with > //a NULL char but not a constant > //literal > > > There are some important but subtle differences between "true" string > literals and strings formed by manually creating arrays of chars as > shown in the technique of Example B and Example D. We can see an > example of this difference in the following code. > > Make a new directory and in GVIM or the editor of your choice create the > following files: > > test.cc > > ------------------------------------------ > #include > #include "test.h" > using namespace std; > > int main(int argc, char * argv[]){ > stringexample(); > return 0; > } > > > ---------------------------------------------- > > test.h > > ---------------------------------------------- > > #ifndef TEST_H > #define TEST_H > #endif /* TEST_H */ > > void stringexample(); > > -------------------------------------------------- > > string_ex.cc > > -------------------------------------------------- > > #include > #include "test.h" > using namespace std; > > void stingexample(){ > > char test[] = "My Dog has Fleas\n"; > const char * test2 = "My Dog has Fleas\n"; > cout << test; > test[3] = 'C'; > test[4] = 'a'; > test[5] = 't'; > cout << test; > cout << test2; > const_cast(test2[3] = 'C'); > const_cast(test2[4] = 'a'); > const_cast(test2[5] = 't'); > cout << test2; > > }
I'd like to make a correction here as follows
void stingexample(){
char test[] = "My Dog has Fleas\n"; const char * test2 = "My Dog has Fleas\n"; cout << test; test[3] = 'C'; test[4] = 'a'; test[5] = 't'; cout << test; cout << test2; const_cast(test2[3]) = 'C'; const_cast(test2[4]) = 'a'; const_cast(test2[5]) = 't'; cout << test2;
> > -------------------------------------------------- > > test.cc > > -------------------------------------------------- > > #include > #include "test.h" > using namespace std; > > int main(int argc, char * argv[]){ > stringexample(); > return 0; > } > > ---------------------------------------------------- > > and create the following makefile > > > ---------------------------------------------------- > > test.bin : test.o string_ex.o > g++ -Wall -o test.bin test.o string_ex.o > > test.o : test.cc > g++ -Wall -c test.cc > > string_ex.o : string_ex.cc test.h > g++ -Wall -c string_ex.cc > > ---------------------------------------------------- > > Note that the makefile MUST have those TABS and not spaces > > Then run 'make' > > gcc gives you the following output > > g++ -Wall -c string_ex.cc > string_ex.cc: In function ?void stingexample()?: > string_ex.cc:15: error: assignment of read-only location ?*(test2 + 3u)? > string_ex.cc:15: error: invalid use of const_cast with type ?char?, > which is not a pointer, reference, nor a pointer-to-data-member type > string_ex.cc:16: error: assignment of read-only location ?*(test2 + 4u)? > string_ex.cc:16: error: invalid use of const_cast with type ?char?, > which is not a pointer, reference, nor a pointer-to-data-member type > string_ex.cc:17: error: assignment of read-only location ?*(test2 + 5u)? > string_ex.cc:17: error: invalid use of const_cast with type ?char?, > which is not a pointer, reference, nor a pointer-to-data-member type > make: *** [string_ex.o] Error 1 > > > This is a very useful error message and the GCC compiler is now taking > the programming to school. Lets look at the complaints of the compiler > about our code. The first problem gcc makes is about line 15 in > string_ex.cc which is this line: > > const_cast(test2[3] = 'C'); > > The compiler is telling us that array (or string) and test2 points to is > read only. That variable is defined on line 8: > > const char * test2 = "My Dog has Fleas\n"; > > It is obvious from the code that the data is defined as a "const", less > obvious is that the compiler will complain and refuse to compile if you > do NOT make test2 a "const". Because of the assignment of the string > literal to the char pointer, it must be a const. Therefore, we tried to > cast the const away with const_cast, and that fails as well > because, as the compiler says to us: > > invalid use of const_cast with type ?char?, which is not a pointer, > reference, nor a pointer-to-data-member type. We can not just cast away > to constantness of the string literal assigned to test2. > > So again we see that arrays and pointers have differences, and arrays > and strings have even great differences. The standard iostream object > "cout" will recognize both as strings for printing to standard output. > > > > Ruben >
|
|