1)
main()
{
char a[4]="HELLO";
printf("%s",a);
}
Answer:
Compiler error: Too many initializers
Explanation:
The array a is of size 4 but the string constant requires 6 bytes to get
stored.
174)
main()
{
char a[4]="HELL";
printf("%s",a);
}
Answer:
HELL%@!~@!@???@~~!
Explanation:
The character array has the memory just enough to hold the string
“HELL” and doesnt have enough space to store the terminating null
character. So it prints the HELL correctly and continues to print garbage
values till it accidentally comes across a NULL character.
Thursday, October 21, 2010
Friendship isn't inherited, transitive, or reciprocal
Just because I grant you friendship access to me doesn't automatically grant your kids access to me, doesn't automatically grant your friends access to me, and doesn't automatically grant me access to you.
- I don't necessarily trust the kids of my friends. The privileges of friendship aren't inherited. Derived classes of a friend aren't necessarily friends. If class Fred declares that class Base is a friend, classes derived from Base don't have any automatic special access rights to Fred objects.
- I don't necessarily trust the friends of my friends. The privileges of friendship aren't transitive. A friend of a friend isn't necessarily a friend. If class Fred declares class Wilma as a friend, and class Wilma declares class Betty as a friend, class Betty doesn't necessarily have any special access rights to Fred objects.
- You don't necessarily trust me simply because I declare you my friend. The privileges of friendship aren't reciprocal. If class Fred declares that class Wilma is a friend, Wilma objects have special access to Fred objects but Fred objects do not automatically have special access to Wilma objects.
Should I design my classes from the outside (interfaces first) or from the inside (data first)?
First think about what the object logically represents, not how you intend to physically build it. For example, suppose you have a Stack class that will be built by containing a LinkedList:
get() method that returns the LinkedList? Or a set() method that takes a LinkedList? Or a constructor that takes a LinkedList? Obviously the answer is No, since you should design your interfaces from the outside-in. I.e., users of Stack objects don't care about LinkedLists; they care about pushing and popping.
Now for another example that is a bit more subtle. Suppose class LinkedList is built using a linked list of Node objects, where each Node object has a pointer to the next Node:
get() method that will let users access the first Node? Should the Node object have a get() method that will let users follow that Node to the next Node in the chain? In other words, what should a LinkedList look like from the outside? Is a LinkedList really a chain of Node objects? Or is that just an implementation detail? And if it is just an implementation detail, how will the LinkedList let users access each of the elements in the LinkedList one at a time?
The key insight is the realization that a LinkedList is not a chain of Nodes. That may be how it is built, but that is not what it is. What it is is a sequence of elements. Therefore the LinkedList abstraction should provide a LinkedListIterator class as well, and that LinkedListIterator might have anoperator++ to go to the next element, and it might have a get() /set() pair to access its value stored in the Node (the value in the Node element is solely the responsibility of the LinkedList user, which is why there is a get() /set() pair that allows the user to freely manipulate that value).
Starting from the user's perspective, we might want our LinkedList class to support operations that look similar to accessing an array using pointer arithmetic:
begin() method and an end() method. These return a LinkedListIterator object. The LinkedListIterator will need a method to go forward, ++p ; a method to access the current element, *p ; and a comparison operator, p != a.end() .
The code follows. The important thing to notice is that LinkedList does not have any methods that let users access Nodes. Nodes are an implementation technique that is completely buried. This makes the LinkedList class safer (no chance a user will mess up the invariants and linkages between the various nodes), easier to use (users don't need to expend extra effort keeping the node-count equal to the actual number of nodes, or any other infrastructure stuff), and more flexible (by changing a single typedef, users could change their code from using LinkedList to some other list-like class and the bulk of their code would compile cleanly and hopefully with improved performance characteristics).
Thus the onlyget() /set() methods were to get and set the elements of the linked list, but not the infrastructure of the linked list. Since the linked list hides the infrastructure pointers/etc., it is able to make very strong promises regarding that infrastructure (e.g., if it were a doubly linked list, it might guarantee that every forward pointer was matched by a backwards pointer from the next Node).
So, we see here an example of where the values of some of a class's data is the responsibility of users (in which case the class needs to haveget() /set() methods for that data) but the data that the class wants to control does not necessarily have get() /set() methods.
Note: the purpose of this example is not to show you how to write a linked-list class. In fact you should not "roll your own" linked-list class since you should use one of the "container classes" provided with your compiler. Ideally you'll use one of the standard container classes such as thestd::list<T> template.
class Stack {
public:
...
private:
LinkedList list_;
};
Should the Stack have a public:
...
private:
LinkedList list_;
};
Now for another example that is a bit more subtle. Suppose class LinkedList is built using a linked list of Node objects, where each Node object has a pointer to the next Node:
class Node { /*...*/ };
class LinkedList {
public:
...
private:
Node* first_;
};
Should the LinkedList class have a class LinkedList {
public:
...
private:
Node* first_;
};
The key insight is the realization that a LinkedList is not a chain of Nodes. That may be how it is built, but that is not what it is. What it is is a sequence of elements. Therefore the LinkedList abstraction should provide a LinkedListIterator class as well, and that LinkedListIterator might have an
Starting from the user's perspective, we might want our LinkedList class to support operations that look similar to accessing an array using pointer arithmetic:
void userCode(LinkedList& a)
{
for (LinkedListIterator p = a.begin(); p != a.end(); ++p)
std::cout << *p << '\n';
}
To implement this interface, LinkedList will need a {
for (LinkedListIterator p = a.begin(); p != a.end(); ++p)
std::cout << *p << '\n';
}
The code follows. The important thing to notice is that LinkedList does not have any methods that let users access Nodes. Nodes are an implementation technique that is completely buried. This makes the LinkedList class safer (no chance a user will mess up the invariants and linkages between the various nodes), easier to use (users don't need to expend extra effort keeping the node-count equal to the actual number of nodes, or any other infrastructure stuff), and more flexible (by changing a single typedef, users could change their code from using LinkedList to some other list-like class and the bulk of their code would compile cleanly and hopefully with improved performance characteristics).
#include <cassert> // Poor man's exception handling
class LinkedListIterator;
class LinkedList;
class Node {
// No public members; this is a "private class"
friend class LinkedListIterator; // A friend class
friend class LinkedList;
Node* next_;
int elem_;
};
class LinkedListIterator {
public:
bool operator== (LinkedListIterator i) const;
bool operator!= (LinkedListIterator i) const;
void operator++ (); // Go to the next element
int& operator* (); // Access the current element
private:
LinkedListIterator(Node* p);
Node* p_;
friend class LinkedList; // so LinkedList can construct a LinkedListIterator
};
class LinkedList {
public:
void append(int elem); // Adds elem after the end
void prepend(int elem); // Adds elem before the beginning
...
LinkedListIterator begin();
LinkedListIterator end();
...
private:
Node* first_;
};
Here are the methods that are obviously inlinable (probably in the same header file): class LinkedListIterator;
class LinkedList;
class Node {
// No public members; this is a "private class"
friend class LinkedListIterator; // A friend class
friend class LinkedList;
Node* next_;
int elem_;
};
class LinkedListIterator {
public:
bool operator== (LinkedListIterator i) const;
bool operator!= (LinkedListIterator i) const;
void operator++ (); // Go to the next element
int& operator* (); // Access the current element
private:
LinkedListIterator(Node* p);
Node* p_;
friend class LinkedList; // so LinkedList can construct a LinkedListIterator
};
class LinkedList {
public:
void append(int elem); // Adds elem after the end
void prepend(int elem); // Adds elem before the beginning
...
LinkedListIterator begin();
LinkedListIterator end();
...
private:
Node* first_;
};
inline bool LinkedListIterator::operator== (LinkedListIterator i) const
{
return p_ == i.p_;
}
inline bool LinkedListIterator::operator!= (LinkedListIterator i) const
{
return p_ != i.p_;
}
inline void LinkedListIterator::operator++()
{
assert(p_ != NULL); // orif (p_==NULL) throw ...
p_ = p_->next_;
}
inline int& LinkedListIterator::operator*()
{
assert(p_ != NULL); // orif (p_==NULL) throw ...
return p_->elem_;
}
inline LinkedListIterator::LinkedListIterator(Node* p)
: p_(p)
{ }
inline LinkedListIterator LinkedList::begin()
{
return first_;
}
inline LinkedListIterator LinkedList::end()
{
return NULL;
}
Conclusion: The linked list had two different kinds of data. The values of the elements stored in the linked list are the responsibility of the user of the linked list (and only the user; the linked list itself makes no attempt to prohibit users from changing the third element to 5), and the linked list's infrastructure data (next pointers, etc.), whose values are the responsibility of the linked list (and only the linked list; e.g., the linked list does not let users change (or even look at!) the various next pointers). {
return p_ == i.p_;
}
inline bool LinkedListIterator::operator!= (LinkedListIterator i) const
{
return p_ != i.p_;
}
inline void LinkedListIterator::operator++()
{
assert(p_ != NULL); // or
p_ = p_->next_;
}
inline int& LinkedListIterator::operator*()
{
assert(p_ != NULL); // or
return p_->elem_;
}
inline LinkedListIterator::LinkedListIterator(Node* p)
: p_(p)
{ }
inline LinkedListIterator LinkedList::begin()
{
return first_;
}
inline LinkedListIterator LinkedList::end()
{
return NULL;
}
Thus the only
So, we see here an example of where the values of some of a class's data is the responsibility of users (in which case the class needs to have
Note: the purpose of this example is not to show you how to write a linked-list class. In fact you should not "roll your own" linked-list class since you should use one of the "container classes" provided with your compiler. Ideally you'll use one of the standard container classes such as the
() vs [] for subscripting in case of more than 1 parameter
Use operator() rather than operator[] .
When you have multiple subscripts, the cleanest way to do it is withoperator() rather than with operator[] . The reason is that operator[] always takes exactly one parameter, but operator() can take any number of parameters (in the case of a rectangular matrix, two parameters are needed).
For example:
m(i,j) rather than m[i][j] :
When you have multiple subscripts, the cleanest way to do it is with
For example:
class Matrix {
public:
Matrix(unsigned rows, unsigned cols);
double& operator() (unsigned row, unsigned col); ← subscript operators often come in pairs
double operator() (unsigned row, unsigned col) const; ← subscript operators often come in pairs
...
~Matrix(); // Destructor
Matrix(Matrix const& m); // Copy constructor
Matrix& operator= (Matrix const& m); // Assignment operator
...
private:
unsigned rows_, cols_;
double* data_;
};
inline
Matrix::Matrix(unsigned rows, unsigned cols)
: rows_ (rows)
, cols_ (cols)
//data_ <--initialized below (after the 'if/throw' statement)
{
if (rows == 0 || cols == 0)
throw BadIndex("Matrix constructor has 0 size");
data_ = new double[rows * cols];
}
inline
Matrix::~Matrix()
{
delete[] data_;
}
inline
double& Matrix::operator() (unsigned row, unsigned col)
{
if (row >= rows_ || col >= cols_)
throw BadIndex("Matrix subscript out of bounds");
return data_[cols_*row + col];
}
inline
double Matrix::operator() (unsigned row, unsigned col) const
{
if (row >= rows_ || col >= cols_)
throw BadIndex("const Matrix subscript out of bounds");
return data_[cols_*row + col];
}
Then you can access an element of Matrix m using public:
Matrix(unsigned rows, unsigned cols);
double& operator() (unsigned row, unsigned col); ← subscript operators often come in pairs
double operator() (unsigned row, unsigned col) const; ← subscript operators often come in pairs
...
~Matrix(); // Destructor
Matrix(Matrix const& m); // Copy constructor
Matrix& operator= (Matrix const& m); // Assignment operator
...
private:
unsigned rows_, cols_;
double* data_;
};
inline
Matrix::Matrix(unsigned rows, unsigned cols)
: rows_ (rows)
, cols_ (cols)
//data_ <--initialized below (after the 'if/throw' statement)
{
if (rows == 0 || cols == 0)
throw BadIndex("Matrix constructor has 0 size");
data_ = new double[rows * cols];
}
inline
Matrix::~Matrix()
{
delete[] data_;
}
inline
double& Matrix::operator() (unsigned row, unsigned col)
{
if (row >= rows_ || col >= cols_)
throw BadIndex("Matrix subscript out of bounds");
return data_[cols_*row + col];
}
inline
double Matrix::operator() (unsigned row, unsigned col) const
{
if (row >= rows_ || col >= cols_)
throw BadIndex("const Matrix subscript out of bounds");
return data_[cols_*row + col];
}
int main()
{
Matrix m(10,10);
m(5,8) = 106.15;
std::cout << m(5,8);
...
}
{
Matrix m(10,10);
m(5,8) = 106.15;
std::cout << m(5,8);
...
}
Matrix class is not array of arrays
The same reasons you encapsulate your data structures, and the same reason you check parameters to make sure they are valid.
A few people use[][] despite its limitations, arguing that [][] is better because it is faster or because it uses C-syntax. The problem with the "it's faster" argument is that it's not — at least not on the latest version of two of the world's best known C++ compilers. The problem with the "uses C-syntax" argument is that C++ is not C. Plus, oh yea, the C-syntax makes it harder to change the data structure and harder to check parameter values.
The point of the previous two FAQs is thatm(i,j) gives you a clean, simple way to check all the parameters and to hide (and therefore, if you want to, change) the internal data structure. The world already has way too many exposed data structures and way too many out-of-bounds parameters, and those cost way too much money and cause way too many delays and way too many defects.
Now everybody knows that you are different. You are clairvoiant with perfect knowledge of the future, and you know that no one will ever find any benefit from changing your matrix's internal data structure. Plus you are a good programmer, unlike those slobs out there that occasionally pass wrong parameters, so you don't need to worry about pesky little things like parameter checking. But even though you don't need to worry about maintenance costs (no one ever needs to change your code), there might be one or two other programmers who aren't quite perfect yet. For them, maintenance costs are high, defects are real, and requirements change. Believe it or not, every once in a while they need to (better sit down) change their code.
Okay, my thongue wath in my theek. But there was a point. The point was that encapsulation and parameter-checking are not crutches for the weak. It's smart to use techniques that make encapsulation and/or parameter checking easy. Them(i,j) syntax is one of those techniques.
Having said all that, if you find yourself maintaining a billion-line app where the original team usedm[i][j] , or even if you are writing a brand new app and you just plain want to use m[i][j] , you can still encapsulate the data structure and/or check all your parameters. It's not even that hard. However it does require a level of sophistication that, like it or not, the average C++ programmers fears. Fortunately you are not average, so read on.
If you merely want to check parameters, just make sure the outeroperator[] returns an object rather than a raw array, then that object's operator[] can check its parameter in the usual way. Beware that this can slow down your program. In particular, if these inner array-like objects end up allocating their own block of memory for their row of the matrix, the performance overhead for creating / destroying your matrix objects can grow dramatically. The theoretical cost is still O(rows*cols), but in practice, the overhead of the memory allocator (new or malloc) can be much larger than anything else, and that overhead can swamp the other costs. For instance, on two of the world's best known C++ compilers, the separate-allocation-per-row technique was 10x slower than the than one-allocation-for-the-entire-matrix technique. 10% is one thing, 10x is another.
If you want to check the parameters without the above overhead and/or if you want to encapsulate (and possibly change) the matrix's internal data structure, follow these steps:
Matrix::ConstRow . Don't forget to use Matrix const& instead of Matrix& .
Final step: find the joker who failed to read the previous FAQ and thonk him in the noggin.
If you have a decent compiler and if you judiciously use inlining, the compiler should optimize away the temporary objects. In other words, theoperator[] -approach above will hopefully not be slower than what it would have been if you had directly called Matrix::operator()(unsigned row, unsigned col) in the first place. Of course you could have made your life simpler and avoided most of the above work by directly calling Matrix::operator()(unsigned row, unsigned col) in the first place. So you might as well directly call Matrix::operator()(unsigned row, unsigned col) in the first place.
A few people use
The point of the previous two FAQs is that
Now everybody knows that you are different. You are clairvoiant with perfect knowledge of the future, and you know that no one will ever find any benefit from changing your matrix's internal data structure. Plus you are a good programmer, unlike those slobs out there that occasionally pass wrong parameters, so you don't need to worry about pesky little things like parameter checking. But even though you don't need to worry about maintenance costs (no one ever needs to change your code), there might be one or two other programmers who aren't quite perfect yet. For them, maintenance costs are high, defects are real, and requirements change. Believe it or not, every once in a while they need to (better sit down) change their code.
Okay, my thongue wath in my theek. But there was a point. The point was that encapsulation and parameter-checking are not crutches for the weak. It's smart to use techniques that make encapsulation and/or parameter checking easy. The
Having said all that, if you find yourself maintaining a billion-line app where the original team used
If you merely want to check parameters, just make sure the outer
If you want to check the parameters without the above overhead and/or if you want to encapsulate (and possibly change) the matrix's internal data structure, follow these steps:
- Add
operator()(unsigned row, unsigned col) to the Matrix class. - Create nested class
Matrix::Row . It should have a ctor with parameters(Matrix& matrix, unsigned row) , and it should store those two values in its this object. - Change
Matrix::operator[](unsigned row) so it returns an object of classMatrix::Row , e.g.,{ return Row(*this,row); } . - Class
Matrix::Row then defines its ownoperator[](unsigned col) which turns around and calls, you guessed it,Matrix::operator()(unsigned row, unsigned col) . If theMatrix::Row data members are calledMatrix& matrix_ andunsigned row_ , the code forMatrix::Row::operator[](unsigned col) will be{ return matrix_(row_, col); }
Final step: find the joker who failed to read the previous FAQ and thonk him in the noggin.
If you have a decent compiler and if you judiciously use inlining, the compiler should optimize away the temporary objects. In other words, the
Overloading < And >
Without friend
int operator > (const Complex& right) const { return (real > right.getReal() && img > right.getImg(); }
Using Friend
friend int operator < (const Complex& left, const Complex& right){----//TODO}
int operator > (const Complex& right) const { return (real > right.getReal() && img > right.getImg(); }
Using Friend
friend int operator < (const Complex& left, const Complex& right){----//TODO}
Operator Overloading in c++
In C++ the overloading principle applies not only to functions, but to operators too. That is, the meaning of operators can be extended from built-in types to user-defined types. In this way a programmer can provide his or her own operator to a class by overloading the built-in operator to perform some specific computation when the operator is used with objects of that class.
One question may arise here: is this really useful in real world implementations? Some programmers consider that overloading is not useful most of the time. This and the fact that overloading makes the language more complicated is the main reason why operator overloading is banned in Java.
Even if overloading adds complexity to the language it can provide a lot of syntactic sugar, and code written by a programmer using operator overloading can be easy, but sometimes misleading, to read. We can use operator overloading easily without knowing all the implementation's complexities. A short example will make things clear:
In order to be able to write the above code we must have the "+" operator overloaded to make the proper addition between the real members and the imaginary ones and also the assignment operator. The overloading syntax is quite simple, similar to function overloading, the keyword operator followed by the operator we want to overload as you can see in the next code sample:
The motivation for doing so can be understood by examining the difference between the two choices: when the operator is a member the first object in the expression must be of that particular type, when it's a global function, the implicit or user-defined conversion can allow the operator to act even if the first operand is not exactly of the same type:
Another intuitive meaning of the "+" operator from the STL string class which is overloaded to do concatenation:
The operators which cannot be overloaded -scope resolution (::), member selection (.), and member selection through a pointer to a function(.*), preprocessor convert to string(#), preprocessor concatenate (##)...See more here.
One question may arise here: is this really useful in real world implementations? Some programmers consider that overloading is not useful most of the time. This and the fact that overloading makes the language more complicated is the main reason why operator overloading is banned in Java.
Even if overloading adds complexity to the language it can provide a lot of syntactic sugar, and code written by a programmer using operator overloading can be easy, but sometimes misleading, to read. We can use operator overloading easily without knowing all the implementation's complexities. A short example will make things clear:
Complex a(1.2,1.3); //this class is used to represent complex numbersThe addition without having overloaded operator + could look like this:
Complex b(2.1,3); //notice the construction taking 2 parameters for the real and imaginary part
Complex c = a+b; //for this to work the addition operator must be overloaded
a.Add(b);This piece of code is not as suggestive as the first one and the readability becomes poor. Using operator overloading is a design decision, so when we deal with concepts where some operator seems fit and its use intuitive, it will make the code more clear than using a function to do the task. However, there are many cases when programmers abuse this technique, when the concept represented by the class is not related to the operator (like using + and - to add and remove elements from a data structure). In this cases operator overloading is a bad idea, creating confusion.
Complex c(a);
In order to be able to write the above code we must have the "+" operator overloaded to make the proper addition between the real members and the imaginary ones and also the assignment operator. The overloading syntax is quite simple, similar to function overloading, the keyword operator followed by the operator we want to overload as you can see in the next code sample:
class ComplexThe assignment operator can be overloaded similarly. Notice that we had to call the accessor function in order to get the real and imaginary parts from the parameter since they are private. In order to bypass this difficulty we could have made the operator + a friend.
{
public:
Complex(double re,double im)
:real(re),imag(im)
{};
Complex operator+(Complex);
Complex operator=(Complex);
private:
double real;
double imag;
}
Complex Complex::operator+(Complex num)
{
real = real + num.GetRealPart();
imag = imag + num.GetImagPart();
return *this;
}
friend Complex operator+(Complex);We could have defined the addition operator globally and called a member to do the actual work:
Complex operator+(Complex &num1,Complex &num2)
{
Complex temp(num1); //note the use of a copy constructor here
temp.Add(num2);
return temp;
}
The motivation for doing so can be understood by examining the difference between the two choices: when the operator is a member the first object in the expression must be of that particular type, when it's a global function, the implicit or user-defined conversion can allow the operator to act even if the first operand is not exactly of the same type:
Complex c = 2+b; //if the integer 2 can be converted by the Complex class, this expression is validThe number of operands can't be overridden, that is, a binary operator takes two operands, a unary only one. The same restriction acts for the precedence too, for example the multiplication takes place before addition. There are some operators that need the first operand to be left value: operator=, operator(), operator[] and operator->, so their use is restricted just as member functions(non-static), they can't be overloaded globally. The operator=, operator& and operator, (sequencing) have already defined meanings by default for all objects, but their meanings can be changed by overloading or erased by making them private.
Another intuitive meaning of the "+" operator from the STL string class which is overloaded to do concatenation:
string prefix("de");Using "+" to concatenate is also allowed in Java, but note that this is not extensible to other classes, and it's not a user defined behavior. Almost all operators can be overloaded in C++:
string word("composed");
string composed = prefix+word;
+ - * / % ^ & |
~ ! , = < > <= >=
++ -- << >> == != && ||
+= -= /= %= ^= & = |= *=
<<= >>= [ ] ( ) -> ->* new delete
The operators which cannot be overloaded -scope resolution (::), member selection (.), and member selection through a pointer to a function(.*), preprocessor convert to string(#), preprocessor concatenate (##)...See more here.
Tuesday, October 19, 2010
Stack in C++
#include <iostream>
using
namespace
std;
#define STACKSIZE 10
class
stack
{
private
:
int
arr[STACKSIZE+1];
int
tos;
public
:
stack();
void
push(
int
x);
int
pop();
bool
is_empty();
bool
is_full();
int
size();
void
display();
};
stack::stack()
{
tos = 0;
}
void
stack::push(
int
x)
{
if
(!is_full())
arr[tos++] = x;
else
cout <<
"Stack is full, Can not push "
<< x << endl;
}
int
stack::pop()
{
if
(!is_empty())
return
arr[--tos];
else
cout <<
"Stack is empty, cannot pop"
<< endl;
return
-1;
}
bool
stack::is_empty()
{
if
(tos == 0)
return
true
;
else
return
false
;
}
bool
stack::is_full()
{
if
(tos == STACKSIZE)
return
true
;
else
return
false
;
}
int
stack::size()
{
return
tos;
}
void
stack::display()
{
if
(tos == 0)
{
cout <<
"No elements to display"
<< endl;
return
;
}
for
(
int
i=0;i
cout << arr[i] <<
" "
;
cout << endl;
}
int
main()
{
stack mystack;
cout << mystack.size() << endl;
mystack.push(1);
if
(mystack.is_full())
cout <<
"stack is full"
<< endl;
mystack.pop();
if
(mystack.is_empty())
cout <<
"stack is empty"
<< endl;
}
Sunday, October 17, 2010
Some terms and their synonyms in programming languages
Scope/Visibility
Nested/Inner Class
Instance/Member
Class/Static
Local/Automatic variable
Nested/Inner Class
Instance/Member
Class/Static
Local/Automatic variable
Subscribe to:
Posts (Atom)