Breaking a switch and a for loop?

Started by
24 comments, last by Zahlman 16 years, 1 month ago
Quote:Original post by yewbie
struct ANIMTILES{	int x;	int y;	int layer;	int iTile;	int iOrignalTile;	DWORD iLastTickCount; //this is the last tick we changed the tile	DWORD iAnimSpeed;//speed in MS of animation	int iAnimNum;//number of tiles in the animation};ANIMTILES MyAnimTiles[MAX_ANIM_TILES];



Just a pit of advice, and some kool knowledge you can chage the last line from
'};ANIMTILES MyAnimTiles[MAX_ANIM_TILES];'
to
'} MyAnimTiles[MAX_ANIM_TILES];'
and get the same thing.. Might save you time later, and Is also used with anonymous structs...

Say it with me
KNOWLEDGE IS POWER
Advertisement
Quote:Original post by Intrigue7
I'm a C programmer and I am wondering why you consider Hungarian notation as useless..


C++ already checks types for you. Hungarian notation is nothing more than redundant in C++. And with a half-decent IDE, you can find out all the information that it provides in a fraction of a second. Read this article for an explanation of using Hungarian notation helpfully rather than redundantly.
for(int i=0;;i++){  switch(i)  {    case 10: goto stop;  }}stop:

Edit: I just realized gekko beat me to it.

[Edited by - kloffy on February 23, 2008 7:04:18 PM]
Quote:Original post by yewbie
what im not understanding is this
std::vector<Tile>::iterator end = animatedTiles.end();for (std::vector<Tile>::iterator it = animatedTiles.begin(); i != end; ++it)


Isn't there an error in the loop condition? It should be it instead of i, right?
Quote:Original post by Intrigue7
Quote:
Anyway, while I'm on this step, I'm going to fix up some names to be a little more consistent, mostly by getting rid of the useless Hungarian notation. The C++ type system is much stronger than C's, and it wants to help you; let it.


I'm a C programmer and I am wondering why you consider Hungarian notation as useless.. It intrigued me so I started to dig more info on google and everyone seems to agree with you... But... I still do not know why.. lol. I'd appreciate a small clarification on this. Also, what do you mean by C++ type system wants to help you ?


The primary reason you don't understand this is because you are a C programmer. :) The basic idea is that the whole point of having a type system is to catch type errors; otherwise, it is getting in your way. The idea with Hungarian notation is to supplement the "physical" type of a variable (the one the compiler understands) with a "logical" one (as indicated by the prefix). This loses the benefit of "the compiler understands", and comes at the expense of making humans do extra work to think about these cryptic prefixes.

In C++, we can create new types easily. Consider, for example, Joel Spolsky's example with "safe" and "unsafe" strings. Granted, his example is for PHP, which is dynamically typed. (I've often wanted to do Hungarian notation in my Python code, but it seems that some combination of unit testing and explicit type checking works much better.)

All we do is create the "safe string" type, by making a structure and writing the relevant functionality. Unsafe strings can continue to be represented with std::string. By requiring explicit conversions from unsafe -> safe, we cannot use an unsafe string without "escaping" it.

class SafeString {  std::string data;  explicit SafeString(const std::string& unsafe); // does the escaping logic.  public:  // The concatenation of two SafeStrings is always safe.  SafeString& operator+=(const SafeString& ss) { data += ss.data; return *this; }  SafeString operator+(const SafeString& ss) { return SafeString(*this) += ss; }  // We can't modify a SafeString's characters directly, because we could  // inject an unsafe character. But we can read them:  char operator[](size_t index) const { return data[index]; }  friend ostream& operator<<(ostream& os, const SafeString& ss) { return os << data; }  // etc. etc.  // Force clients to use a named function instead of a constructor, to make it  // clear what is going on. This, strictly speaking, probably isn't necessary.  friend SafeString escape(const std::string& unsafe) { return SafeString(unsafe); }  std::string unescape() { return data; } // makes an "unsafe" copy.};

Quote:Original post by DevFred
Quote:Original post by yewbie
what im not understanding is this
std::vector<Tile>::iterator end = animatedTiles.end();for (std::vector<Tile>::iterator it = animatedTiles.begin(); i != end; ++it)


Isn't there an error in the loop condition? It should be it instead of i, right?


Er, yes. That was a typo. x.x

yewbie: lists, vectors, etc. are specific cases of the general concept of a container. It means basically what it looks like: we have an "iterator" object, which iterates through the container - 'incrementing' it causes it to "point to" the next element of the container, and 'dereferencing' it gives us the "pointed-at" element. (The "iterator" concept is inspired by old-fashioned pointers, but they are more general-purpose. Actually, ordinary pointers are a kind of iterator: they are the iterator for arrays, which are a limited kind of container.)

The container provides a ".begin" member function, which creates and returns an iterator pointing to the beginning of the container, and a ".end" member function, creating an iterator pointing "just past" the end of the container. That's done so that you can compare to it without the implementors needing to define "less than" or "greater than" for iterators: you just use "equal" or "not equal". When the iterator is equal to the .end(), it has *just now* stepped out of bounds, so we are done. It hasn't been *dereferenced* out of bounds, so nothing Bad(TM) will happen. (One of the "limits" of arrays as a container is that, because they aren't *objects*, they can't provide .begin() and .end(). Instead, the begin is simply the name of the array, decayed to a pointer; and the end is that value, plus the number of elements in the array.)

This topic is closed to new replies.

Advertisement