Expand|Select|Wrap|Line Numbers
- int array[5];
Expand|Select|Wrap|Line Numbers
- int array[];
x = 1;What does this do, assign the number one or the color yellow to x?
const int RED = 0;Now it's easy to distinguish between assignment of the number 1 and the color yellow.
const int YELLOW = 1;
const int GREEN = 2;
int y;There is still the problem that we declare x as an int altho it's a color.
int x;
. . .
y = 1; // assigns the integer one
x = YELLOW; // assigns yellow (which happens to be 1).
enum
statement to assign sequential integer values to names and provide a type name for declaration. enum TrafficLightColor {RED, YELLOW, GREEN};The enum declaration creates a new integer type. By convention the first letter of an enum type should be in uppercase. The list of values follows, where the first name is assigned zero, the second 1, etc.
. . .
int y;
TrafficLightColor x;
. . .
y = 1;
x = YELLOW;
enum TrafficLightColor {RED, YELLOW, GREEN};
enum Gender {MALE, FEMALE};
TrafficLightColor x;
int i;
. . .
x = YELLOW; // good
i = x; // Legal, but bad style. Assigns the integer representation.
i = (int)x; // As above, explicit casting is better style.
x = (TrafficLightColor)2; // Legal, but very dangerous. No checking.
x = FEMALE; // BAD, Compiler may give error or warning.
x = 5; // BAD, Compiler may give error or warning.
enum ColorT {red, orange, yellow, green, blue, indigo, violet};In the above example, the effect of the enumeration is to introduce several new constants named red, orange, yellow, etc. By default, these constants are assigned consecutive integer values starting at zero. You can change the values of those constants, as shown by the next example:
...
ColorT c1 = indigo;
if( c1 == indigo ) {
cout << "c1 is indigo" << endl;
}
enum ColorT { red = 10, blue = 15, green };When executed, the above code will display the following output:
...
ColorT c = green;
cout << "c is " << c << endl;
c is 16Note that the above examples will only work with C++ compilers. If you're working in regular C, you will need to specify the enum keyword whenever you create an instance of an enumerated type:
enum ColorT { red = 10, blue = 15, green };Alternatively, add a typedef to bring C and C++ on par:
...
enum ColorT c = green; /* note the additional enum keyword */
printf( "c is %d\n", c );
typedef enum ColorT { red = 10, blue = 15, green } ColorT;
...
ColorT c = green; /* no more additional enum keyword */
printf( "c is %d\n", c );
// 2.1 define a function pointer and initialize to NULL
int (*pt2Function)(float, char, char) = NULL; // C
int (TMyClass::*pt2Member)(float, char, char) = NULL; // C++
int (TMyClass::*pt2ConstMember)(float, char, char) const = NULL; // C++
// 2.2 define the calling convention
void __cdecl DoIt(float a, char b, char c); // Borland and Microsoft
void DoIt(float a, char b, char c) __attribute__((cdecl)); // GNU GCC
// 2.3 assign an address to the function pointer
// Note: Although you may ommit the address operator on most compilers
// you should always use the correct way in order to write portable code.
// C
int DoIt (float a, char b, char c){ printf("DoIt\n"); return a+b+c; }
int DoMore(float a, char b, char c)const{ printf("DoMore\n"); return a-b+c; }
pt2Function = DoIt; // short form
pt2Function = &DoMore; // correct assignment using address operator
// C++
class TMyClass
{
public:
int DoIt(float a, char b, char c){ cout << "TMyClass::DoIt"<< endl; return a+b+c;};
int DoMore(float a, char b, char c) const
{ cout << "TMyClass::DoMore" << endl; return a-b+c; };
/* more of TMyClass */
};
pt2ConstMember = &TMyClass::DoMore; // correct assignment using address operator
pt2Member = &TMyClass::DoIt; // note: may also legally point to &DoMore
// 2.4 comparing function pointers
// C
if(pt2Function >0){ // check if initialized
if(pt2Function == &DoIt)
printf("Pointer points to DoIt\n"); }
else
printf("Pointer not initialized!!\n");
// C++
if(pt2ConstMember == &TMyClass::DoMore)
cout << "Pointer points to TMyClass::DoMore" << endl;
// 2.5 calling a function using a function pointer
int result1 = pt2Function (12, 'a', 'b'); // C short way
int result2 = (*pt2Function) (12, 'a', 'b'); // C
TMyClass instance1;
int result3 = (instance1.*pt2Member)(12, 'a', 'b'); // C++
int result4 = (*this.*pt2Member)(12, 'a', 'b'); // C++ if this-pointer can be used
TMyClass* instance2 = new TMyClass;
int result4 = (instance2->*pt2Member)(12, 'a', 'b'); // C++, instance2 is a pointer
delete instance2;
//------------------------------------------------------------------------------------
// 2.6 How to Pass a Function Pointer
// is a pointer to a function which returns an int and takes a float and two char
void PassPtr(int (*pt2Func)(float, char, char))
{
int result = (*pt2Func)(12, 'a', 'b'); // call using function pointer
cout << result << endl;
}
// execute example code - 'DoIt' is a suitable function like defined above in 2.1-4
void Pass_A_Function_Pointer()
{
cout << endl << "Executing 'Pass_A_Function_Pointer'" << endl;
PassPtr(&DoIt);
}
//------------------------------------------------------------------------------------
// 2.7 How to Return a Function Pointer
// 'Plus' and 'Minus' are defined above. They return a float and take two float
// Direct solution: Function takes a char and returns a pointer to a
// function which is taking two floats and returns a float.
// specifies which function to return
float (*GetPtr1(const char opCode))(float, float)
{
if(opCode == '+')
return &Plus;
else
return &Minus; // default if invalid operator was passed
}
// Solution using a typedef: Define a pointer to a function which is taking
// two floats and returns a float
typedef float(*pt2Func)(float, float);
// Function takes a char and returns a function pointer which is defined
// with the typedef above. specifies which function to return
pt2Func GetPtr2(const char opCode)
{
if(opCode == '+')
return &Plus;
else
return &Minus; // default if invalid operator was passed
}
// Execute example code
void Return_A_Function_Pointer()
{
cout << endl << "Executing 'Return_A_Function_Pointer'" << endl;
// define a function pointer and initialize it to NULL
float (*pt2Function)(float, float) = NULL;
pt2Function=GetPtr1('+'); // get function pointer from function 'GetPtr1'
cout << (*pt2Function)(2, 4) << endl; // call function using the pointer
pt2Function=GetPtr2('-'); // get function pointer from function 'GetPtr2'
cout << (*pt2Function)(2, 4) << endl; // call function using the pointer
}
//------------------------------------------------------------------------------------
// 2.8 How to Use Arrays of Function Pointers
// C ---------------------------------------------------------------------------------
// type-definition: 'pt2Function' now can be used as type
typedef int (*pt2Function)(float, char, char);
// illustrate how to work with an array of function pointers
void Array_Of_Function_Pointers()
{
printf("\nExecuting 'Array_Of_Function_Pointers'\n");
// define arrays and ini each element to NULL,and are arrays
// with 10 pointers to functions which return an int and take a float and two char
// first way using the typedef
pt2Function funcArr1[10] = {NULL};
// 2nd way directly defining the array
int (*funcArr2[10])(float, char, char) = {NULL};
// assign the function's address - 'DoIt' and 'DoMore' are suitable functions
// like defined above in 2.1-4
funcArr1[0] = funcArr2[1] = &DoIt;
funcArr1[1] = funcArr2[0] = &DoMore;
/* more assignments */
// calling a function using an index to address the function pointer
printf("%d\n", funcArr1[1](12, 'a', 'b')); // short form
printf("%d\n", (*funcArr1[0])(12, 'a', 'b')); // "correct" way of calling
printf("%d\n", (*funcArr2[1])(56, 'a', 'b'));
printf("%d\n", (*funcArr2[0])(34, 'a', 'b'));
}
// C++ -------------------------------------------------------------------------------
// type-definition: 'pt2Member' now can be used as type
typedef int (TMyClass::*pt2Member)(float, char, char);
// illustrate how to work with an array of member function pointers
void Array_Of_Member_Function_Pointers()
{
cout << endl << "Executing 'Array_Of_Member_Function_Pointers'" << endl;
// define arrays and ini each element to NULL,and are
// arrays with 10 pointers to member functions which return an int and take
// a float and two char
// first way using the typedef
pt2Member funcArr1[10] = {NULL};
// 2nd way of directly defining the array
int (TMyClass::*funcArr2[10])(float, char, char) = {NULL};
// assign the function's address - 'DoIt' and 'DoMore' are suitable member
// functions of class TMyClass like defined above in 2.1-4
funcArr1[0] = funcArr2nd use an array of function pointers in C and C++. The first way uses a typedef, the second way directly defines the array. It's up to you which way you prefer.
[1] = &TMyClass::DoIt;
funcArr1[1] = funcArr2[0] = &TMyClass::DoMore;
/* more assignments */
// calling a function using an index to address the member function pointer
// note: an instance of TMyClass is needed to call the member functions
TMyClass instance;
cout << (instance.*funcArr1[1])(12, 'a', 'b') << endl;
cout << (instance.*funcArr1[0])(12, 'a', 'b') << endl;
cout << (instance.*funcArr2[1])(34, 'a', 'b') << endl;
cout << (instance.*funcArr2[0])(89, 'a', 'b') << endl;
}
//------------------------------------------------------------------------------------
// 1.2 Introductory Example or How to Replace a Switch-Statement
// Task: Perform one of the four basic arithmetic operations specified by the
// characters '+', '-', '*' or '/'.
// The four arithmetic operations ... one of these functions is selected
// at runtime with a swicth or a function pointer
float Plus (float a, float b) { return a+b; }
float Minus (float a, float b) { return a-b; }
float Multiply(float a, float b) { return a*b; }
float Divide (float a, float b) { return a/b; }
// Solution with a switch-statement - specifies which operation to execute
void Switch(float a, float b, char opCode)
{
float result;
// execute operation
switch(opCode)
{
case '+' : result = Plus (a, b); break;
case '-' : result = Minus (a, b); break;
case '*' : result = Multiply (a, b); break;
case '/' : result = Divide (a, b); break;
}
cout << "Switch: 2+5=" << result << endl; // display result
}
// Solution with a function pointer - is a function pointer and points to
// a function which takes two floats and returns a float. The function pointer
// "specifies" which operation shall be executed.
void Switch_With_Function_Pointer(float a, float b, float (*pt2Func)(float, float))
{
float result = pt2Func(a, b); // call using function pointer
cout << "Switch replaced by function pointer: 2-5="; // display result
cout << result << endl;
}
// Execute example code
void Replace_A_Switch()
{
cout << endl << "Executing function 'Replace_A_Switch'" << endl;
Switch(2, 5, /* '+' specifies function 'Plus' to be executed */ '+');
Switch_With_Function_Pointer(2, 5, /* pointer to function 'Minus' */ &Minus);
}
char *strcpy(char *dest, const char *src)
{
char *save = dest;
while(*dest++ = *src++);
return save;
}
vector
will do bounds checking if you use the at()
function, for example:std::vector v(5);
v.at(3) = 10;
v.at(5) = 20; // throws an exception, std::out_of_range
However, if you use operator[]
, there is no bounds checking. (And accessing non-existent elements leads to undefined behavior.)
char *strcpy(char *dest, const char *src)So here first thing that is happening in while loop is dest and src are incremented by 1
{
char *save = dest;
while(*dest++ = *src++);
return save;
}
#include
- You need to include this file in order to use C++’s functions for File I/O.ofstream SaveFile("cpp-home.txt");
SaveFile << "Hello World, from www.cpp-home.com";
- “<<" looks familiar? Yes, you’ve seen it in cout <<. This ("<<") is a predefined operator. Anyway, what this line makes, is to put the text above in the file. As mentioned before, SaveFile is a handle to the opened file stream. So, we write the handle name, << and after it we write the text in inverted commas. If we want to pass variables instead of text in inverted commas, just pass it as a regular use of the cout <<. This way:SaveFile << variablename;
SaveFile.close();
- As we have opened the stream, when we finish using it, we have to close it. SaveFile is an object from class ofstream, and this class (ofstream) has a function that closes the stream. That is the close() function. So, we just write the name of the handle, dot and close(), in order to close the file stream!#include
void main() //the program starts here
{
ifstream OpenFile("cpp-home.txt");
char ch;
while(!OpenFile.eof())
{
OpenFile.get(ch);
cout << ch;
}
OpenFile.close();
}
ifstream OpenFile("cpp-home.txt")
– I suppose this seems a bit more familiar to you, already! ifstream means “input file stream”. In the previous program, it was ofstream, which means “output file stream”. The previous program is to write a file, that’s why it was “output”. But this program is to read from a file, that’s why it is “input”. The rest of the code on this line, should be familiar to you. OpenFile is the object from class ifstream, which will handle the input file stream. And in the inverted commas, is the name of the file to open.char ch;
- Declares an array of type char. Just to remind you- such arrays can hold just one sign from the ASCII table.while(!OpenFile.eof())
– The function eof() returns a nonzero value if the end of the file has been reached. So, we make a while loop, that will loop until we reach the end of the file. So, we will get through the whole file, so that we can read it!OpenFile.get(ch);
- OpenFile is the object from class ifstream. This class declares a function called get(). So, we can use this function, as long as we have an object. The get() function extracts a single character from the stream and returns it. In this example, the get() function takes just one parameter- the variable name, where to put the read character. So, after calling OpenFile.get(ch) it will read one character from the stream OpenFile, and will put this character into the variable ch.cout << ch;
- Display ch, which has the read character.File.close();
- As we have opened the file stream, we need to close it. Use the close() function, to close it! Just as in the previous program!ifstream OpenFile("cpp-home.txt");
ifstream OpenFile;
OpenFile.open("cpp-home.txt");
#include
void read (ifstream &T) //pass the file stream to the function
{
//the method to read a file, that I showed you before
char ch;
while(!T.eof())
{
T.get(ch);
cout << ch;
}
cout << endl << "--------" << endl;
}
void main()
{
ifstream T("file1.txt");
read(T);
T.close();
T.open("file2.txt");
read(T);
T.close();
}
ifstream OpenFile(char *filename, int open_mode);
Name | Description |
---|---|
ios::in | Open file to read |
ios::out | Open file to write |
ios::app | All the date you write, is put at the end of the file. It calls ios::out |
ios::ate | All the date you write, is put at the end of the file. It does not call ios::out |
ios::trunc | Deletes all previous content in the file. (empties the file) |
ios::nocreate | If the file does not exists, opening it with the open() function gets impossible. |
ios::noreplace | If the file exists, trying to open it with the open() function, returns an error. |
ios::binary | Opens the file in binary mode. |
#include
void main()
{
ofstream SaveFile("file1.txt", ios::ate);
SaveFile << "That's new!\n";
SaveFile.close();
}
ios::ate
| ios::binary
fstream File("cpp-home.txt",ios::in | ios::out);
#include
void main()
{
fstream File("test.txt",ios::in | ios::out);
File << "Hi!"; //put "Hi!" in the file
static char str[10]; //when using static, the array is automatically
//initialized, and very cell NULLed
File.seekg(ios::beg); //get back to the beginning of the file
//this function is explained a bit later
File >> str;
cout << str << endl;
File.close();
}
fstream File("test.txt", ios::in | ios::out);
- This line, creates an object from class fstream. At the time of execution, the program opens the file test.txt in read/write mode. This means, that you can read from the file, and put data into it, at the same time.File << "Hi!";
- I beg you know what this is!static char str[10];
- This makes a char array with 10 cells. I suppose static may be unfamiliar to you. If so- ignore it. It just initializes the array when at the time of creation.File.seekg(ios::beg);
- Okay, I want you to understand what this really do, so I will start with something a bit off-topic, but important.while(!OpenFile.eof())
{
OpenFile.get(ch);
cout << ch;
}
ios::beg
- to put it in the beginning of the fileios::end
- to put it at the end of the fileFile.seekg(-5);
File.seekg(40);
File.seekg(-5,ios::end);
File >> str;
- That’s new, too! Well, I believe this line reminds you of cin >> . I fact, it has much to do with it. This line reads one word from the file, and puts it into the specified array.
char str[30]; //the word can’t be more than 30 characters long
while(!OpenFile.eof())
{
OpenFile >> str;
cout << str;
}
char line[100]; //a whole line will be stored here
while(!OpenFile.eof())
{
OpenFile.getline(line,100); //where 100 is the size of the array
cout << line << endl;
}
Xfstream File("cpp-home.txt");
if (!File)
{
cout << "Error opening the file! Aborting…\n";
exit(1);
}
ofstream File("unexisting.txt", ios::nocreate);
ofstream File("filer.txt", ios::nocreate);
ifstream File; //it could also be ofstream
ofstream File1;
File1.open("file1.txt");
cout << File1.is_open() << endl;
ofstream File1;
cout << File1.is_open() << endl;