| | |
C and C++ Timesaving Tips
![]() |
Finding Array Size
Starting Out
When first starting out, we might write some code that initializes an array, perhaps does some manipulation, and then displays the results. It might look something like this (contrived example):
We notice that if we want to change the array dimension, there are several lines of code to edit to make the change. Maintaining code like this is more difficult because in larger sets of code, finding all of the places that need to be changed becomes less trivial.
Using a Symbolic Constant
To avoid this, it is often recommended to use a symbolic constant instead.
Now we can see we only need to change the #define to make a change to the array size. Unfortunately, purveyors of this wisdom often stop there.
The debugging hazard that this leads to often materializes itself in some header that is used to declare dozens of such constants. Some may like this, but I've found this to be a maintenance headache as well. For example, let's take a look at this code fragment.
Is it correct? You can't tell from this alone. You have to find the declaration of the array and double check. That alone is probably not that big of a deal, except when you have data that may be declared far away from this section of code.
Another Way
A cure is such an old piece of code, it's hard to imagine more people aren't aware of it long before they've learned a struct. It works by dividing the total size of the array (in bytes) by the size of the first element of the array (in bytes); this gives the number of elements. This is calculated at compile time.
Now if you want to change the size of the array, you do it in only one place, and that place happens to be right where you define the array. If we saw the following fragment, is it correct?
If array is an array in scope, yes.
Further Considerations
Some programmers may prefer to use a macro to make it easier to read; either of these are examples.
So another way to write this is as follows.
Use With Functions
Finally, if you pass "the array" to a function, you are really only passing a pointer to the first element of the array. In such cases, you should also pass a size parameter to the function.
Starting Out
When first starting out, we might write some code that initializes an array, perhaps does some manipulation, and then displays the results. It might look something like this (contrived example):
void foo(void)
{
int array[10];
int i;
/* Initialize array. */
for ( i = 0; i < 10; ++i )
{
array[i] = i;
}
/* Perform calculations. */
for ( i = 0; i < 10; ++i )
{
array[i] *= 2;
}
/* Print array. */
for ( i = 0; i < 10; ++i )
{
printf("%d,", array[i]);
}
putchar('\n');
}Using a Symbolic Constant
To avoid this, it is often recommended to use a symbolic constant instead.
#define SIZE 10 void bar(void) { int array[SIZE]; int i; /* Initialize array. */ for ( i = 0; i < SIZE; ++i ) { array[i] = i; } /* Perform calculations. */ for ( i = 0; i < SIZE; ++i ) { array[i] *= 2; } /* Print array. */ for ( i = 0; i < SIZE; ++i ) { printf("%d,", array[i]); } putchar('\n'); }
The debugging hazard that this leads to often materializes itself in some header that is used to declare dozens of such constants. Some may like this, but I've found this to be a maintenance headache as well. For example, let's take a look at this code fragment.
C++ Syntax (Toggle Plain Text)
for ( i = 0; i < ASIZE; ++i ) { printf("%d,", array[i]); }
Another Way
A cure is such an old piece of code, it's hard to imagine more people aren't aware of it long before they've learned a struct. It works by dividing the total size of the array (in bytes) by the size of the first element of the array (in bytes); this gives the number of elements. This is calculated at compile time.
void baz(void)
{
int array[10];
size_t i;
/* Initialize array. */
for ( i = 0; i < sizeof array / sizeof *array; ++i )
{
array[i] = i;
}
/* Perform calculations. */
for ( i = 0; i < sizeof array / sizeof *array; ++i )
{
array[i] *= 2;
}
/* Print array. */
for ( i = 0; i < sizeof array / sizeof *array; ++i )
{
printf("%d,", array[i]);
}
putchar('\n');
} C++ Syntax (Toggle Plain Text)
for ( i = 0; i < sizeof array / sizeof *array; ++i ) { printf("%d,", array[i]); }
Further Considerations
Some programmers may prefer to use a macro to make it easier to read; either of these are examples.
C++ Syntax (Toggle Plain Text)
#define ARRAYSIZE(x) (sizeof(x)/sizeof(*(x))) #define NELEM(x) (sizeof(x)/sizeof(x[0]))
void qux(void)
{
int array[10];
size_t i;
/* Initialize array. */
for ( i = 0; i < ARRAYSIZE(array); ++i )
{
array[i] = i;
}
/* Perform calculations. */
for ( i = 0; i < NELEM(array); ++i )
{
array[i] *= 2;
}
/* Print array. */
for ( i = 0; i < ARRAYSIZE(array); ++i )
{
printf("%d,", array[i]);
}
putchar('\n');
}Finally, if you pass "the array" to a function, you are really only passing a pointer to the first element of the array. In such cases, you should also pass a size parameter to the function.
void fum(int *array, size_t size) { size_t i; /* Initialize array. */ for ( i = 0; i < size; ++i ) { array[i] = i; } /* Perform calculations. */ for ( i = 0; i < size; ++i ) { array[i] *= 2; } /* Print array. */ for ( i = 0; i < size; ++i ) { printf("%d,", array[i]); } putchar('\n'); } int main(void) { int myarray[25]; foo(); bar(); baz(); qux(); fum(myarray, ARRAYSIZE(myarray)); return 0; }
"One of the methods used by statists to destroy capitalism consists in establishing controls that tie a given industry hand and foot, making it unable to solve its problems, then declaring that freedom has failed and stronger controls are necessary." --Ayn Rand
This one is entertaining, and useful too. We all know ("we" being C++ programmers who came from C or still use C extensively) that scanf will eat up a format nice and pretty:
If the input stream does not contain an integer followed by a '-' followed by an integer (shush Dave, and humor me), followed by a '-' followed by an integer, the call will fail. Sadly, this useful feature isn't available in C++ unless you use scanf. Using iostreams, you would be forced to do something painful like this (with suitable error handling, of course):
Wouldn't it be nice if we could just do this and be done with it?
Well, unfortunately it's not quite that easy. One could overload operator>> for a pointer to const char, but that kind of invades the implementation's personal space and therefore, is not portable.
To do it would be trivial though:
This was my solution (more or less). I didn't need something portable, and the benefit of clarity was a decisive factor. Looking toward portability though, just as a mental exercise, I also considered the manipulator approach:
It's almost as simple, but using it requires a bit more work:
On a similar note, I also found a similar manipulator useful. The following manipulator will discard all characters in the stream up to (and including) a user defined character delimiter:
This is slightly more complicated than the usual "empty the buffer" call to ignore, designed to flush the stream of interactive input. That job could be performed with a simple moveto request:
But, moveto is useful in parsing as well. 
One can easily imagine how useful these manipulators can be. Not only does the scanf behavior of eating a format work with standard input and output, a clever programmer could easily pair them with stringstreams, fstreams, or even custom streams to solve a whole slew of formatted parsing problems without hacking together something big and ugly.
And with a little bit of extra work, the scan manipulator can be extended to more accurately mimic scanf's format processing.
C++ Syntax (Toggle Plain Text)
scanf ( "%d-%d-%d", &m, &d, &y );
C++ Syntax (Toggle Plain Text)
cin>> m; if ( cin.peek() == '-' ) cin.ignore(); cin>> d; if ( cin.peek() == '-' ) cin.ignore(); cin>> y;
C++ Syntax (Toggle Plain Text)
cin>> m >>"-">> d >>"-">> y;
To do it would be trivial though:
C++ Syntax (Toggle Plain Text)
istream& operator>> ( istream& in, const char *s ) { while ( *s != '\0' && in && in.peek() == *s ) { in.get(); ++s; } if ( *s != '\0' ) in.setstate ( ios::failbit ); return in; }
C++ Syntax (Toggle Plain Text)
class scan { public: scan ( const char *init ): fmt ( init ) {} friend istream& operator>> ( istream& in, const scan& s ) { while ( *s.fmt != '\0' && in && in.peek() == *s.fmt ) { in.get(); ++s.fmt; } if ( *s.fmt != '\0' ) in.setstate ( ios::failbit ); return in; } private: mutable const char *fmt; };
C++ Syntax (Toggle Plain Text)
cin>> m >> scan ( "-" ) >> d >> scan ( "-" ) >> y;
C++ Syntax (Toggle Plain Text)
class moveto { public: moveto ( istream::int_type init ): ch ( init ) {} friend istream& operator>> ( istream& in, const moveto& d ) { if ( in.rdbuf()->in_avail() > 0 ) in.ignore ( numeric_limits<streamsize>::max(), d.ch ); return in; } private: istream::int_type ch; };
C++ Syntax (Toggle Plain Text)
cin>> moveto ( '\n' );

One can easily imagine how useful these manipulators can be. Not only does the scanf behavior of eating a format work with standard input and output, a clever programmer could easily pair them with stringstreams, fstreams, or even custom streams to solve a whole slew of formatted parsing problems without hacking together something big and ugly.
And with a little bit of extra work, the scan manipulator can be extended to more accurately mimic scanf's format processing.
I'm here to prove you wrong.
I know this may not seem like a super time saving technique, but the way you name your variables will help save time and reduce compile time errors.. Having a conventional variable naming format will help keep things organized and easy to read.
Styles
Typically, most variable names get the every other word capitalized. Functions get the first letter of each word capitalized and constants get all of the letters capitalized.
Example:
Variable: First letter of every other word capitalized.
Styles
Typically, most variable names get the every other word capitalized. Functions get the first letter of each word capitalized and constants get all of the letters capitalized.
Example:
Variable: First letter of every other word capitalized.
- char theName[20];
- void GetTheName();
- #define THENAME 20
A Hacker's Mind:
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes..." - J.D.Salinger
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes..." - J.D.Salinger
Reading an Integer
This is in many FAQs elsewhere, so this is just my repackaging of it here.
C Version
C++ Version
This is in many FAQs elsewhere, so this is just my repackaging of it here.
C Version
#include <stdio.h> #include <stdlib.h> int main(void) { char response[32]; /* * Prompt for input. */ fputs ( "Enter your number: ", stdout ); fflush ( stdout ); /* * Read user response. */ if ( fgets ( response, sizeof response, stdin ) != NULL ) { /* * Attempt to convert user's response into an integer using strtol. The * second parameter to strtol allows for greater error checking if used. */ int value = strtol ( response, NULL, 10/* radix or base */ ); /* * No error checking was done, but attempt to display integer value. */ printf ( "value = %d\n", value ); } return 0; } /* my output Enter your number: 12345 value = 12345 */
#include <iostream> #include <string> #include <sstream> int main(void) { std::string response; /* * Prompt for input. */ std::cout << "Enter your number: "; /* * Read user response. */ std::cin >> response; /* * Attempt to convert user's response into an integer using a stringstream. */ std::istringstream convert(response); int value; if ( convert >> value ) { std::cout << "value = " << value << std::endl; } return 0; } /* my output Enter your number: 456879 value = 456879 */
"One of the methods used by statists to destroy capitalism consists in establishing controls that tie a given industry hand and foot, making it unable to solve its problems, then declaring that freedom has failed and stronger controls are necessary." --Ayn Rand
Koenig Lookup
There are three ways to use a name nested in a namespace. Making the namespace open to the current scope with a using directive:
Making only select names open to the current scope with a using declaration:
And explicit qualification of every name for every use:
It's best to never use the using directive unless you know for a fact that you won't have name clashes. That's usually not easily possible, and most people will suggest that you use explicit qualification all the time. The problem with that is explicit qualification is so verbose! Koenig lookup is a trick to shorten some of those names.
Here's a common example:
Koenig lookup says that if a function in a namespace takes an argument from the same namespace, the function need not be qualified because the compiler will look in that namespace for matching functions. So the following is legal C++:
copy takes an ostream_iterator object as an argument. Because both ostream_iterator and copy are members of namespace std, Koenig lookup finds copy via ostream_iterator. A third of the namespace qualification has been removed from this line, and that is a big timesaver when it all adds up.
There are three ways to use a name nested in a namespace. Making the namespace open to the current scope with a using directive:
C++ Syntax (Toggle Plain Text)
using namespace std; cout << "Hello world!" << endl;
C++ Syntax (Toggle Plain Text)
// Make cout and endl available, but nothing else using std::cout; using std::endl; cout << "Hello world!" << endl;
C++ Syntax (Toggle Plain Text)
std::cout << "Hello world!" << std::endl;
Here's a common example:
C++ Syntax (Toggle Plain Text)
vector<int> c; // ... std::copy(c.begin(), c.end(), std::ostream_iterator<int>(std::cout, "\n"));
C++ Syntax (Toggle Plain Text)
copy(c.begin(), c.end(), std::ostream_iterator<int>(std::cout, "\n"));
•
•
Join Date: May 2005
Posts: 82
Reputation:
Solved Threads: 1
suppose you guys are writing a program which uses a number of loops,
use a single variable for all the loop counters and declare the variable to be of register storage class. what happens is that the variable gets stored in the cpu registers and the loops get executed a lot faster.
the syntax is:
register int i;
hope this was helpful.
use a single variable for all the loop counters and declare the variable to be of register storage class. what happens is that the variable gets stored in the cpu registers and the loops get executed a lot faster.
the syntax is:
register int i;
hope this was helpful.
•
•
•
•
Originally Posted by indianscorpion2
declare the variable to be of register storage class. what happens is that the variable gets stored in the cpu registers and the loops get executed a lot faster.
http://www.eskimo.com/~scs/cclass/krnotes/sx7g.html
"One of the methods used by statists to destroy capitalism consists in establishing controls that tie a given industry hand and foot, making it unable to solve its problems, then declaring that freedom has failed and stronger controls are necessary." --Ayn Rand
Avoid Loop Control Using eof()
All over the 'net C++ programmers are taught to "read until end of file". This leads to the following (incorrect) idiom for loop control. Run the above code with the following text file, "file.txt". Your output will be like this. Note the repeated 10.
What To Use Instead
Change your thinking to "while successfully reading input from a file" and know that the state of the stream -- indicating successful input or a failure -- is available from the input operation. The output is now correct. Then, for amusement, change "file.txt" to this. Then run each of the above programs.
Another Example
A similar thing can be done when reading text. Copy this source into "file.txt" and it will print out this code.
Further Reading:
http://www.parashift.com/c++-faq-lit....html#faq-15.2
http://www.parashift.com/c++-faq-lit....html#faq-15.3
http://www.parashift.com/c++-faq-lit....html#faq-15.4
http://www.parashift.com/c++-faq-lit....html#faq-15.5
All over the 'net C++ programmers are taught to "read until end of file". This leads to the following (incorrect) idiom for loop control.
#include <iostream>
#include <fstream>
int main()
{
std::ifstream file("file.txt");
if ( file )
{
int i;
while ( !file.eof() ) // bad!!
{
file >> i;
std::cout << i << ' ';
}
std::cout << std:: endl;
}
return 0;
}•
•
•
•
1 2 3 4 5 6 7 8 9 10
•
•
•
•
1 2 3 4 5 6 7 8 9 10 10
What To Use Instead
Change your thinking to "while successfully reading input from a file" and know that the state of the stream -- indicating successful input or a failure -- is available from the input operation.
#include <iostream>
#include <fstream>
int main()
{
std::ifstream file("file.txt");
if ( file )
{
int i;
while ( file >> i )
{
std::cout << i << ' ';
}
std::cout << std:: endl;
}
return 0;
}•
•
•
•
1 2 3 4 5 6 7 8 9 10
•
•
•
•
1 2 3 4 5 6 7 8 9 1A
Another Example
A similar thing can be done when reading text.
#include <iostream>
#include <fstream>
int main()
{
std::ifstream file("file.txt");
if ( file )
{
char line[80];
while ( file.getline(line, sizeof line) )
{
std::cout << line << '\n';
}
}
return 0;
}Further Reading:
http://www.parashift.com/c++-faq-lit....html#faq-15.2
http://www.parashift.com/c++-faq-lit....html#faq-15.3
http://www.parashift.com/c++-faq-lit....html#faq-15.4
http://www.parashift.com/c++-faq-lit....html#faq-15.5
"One of the methods used by statists to destroy capitalism consists in establishing controls that tie a given industry hand and foot, making it unable to solve its problems, then declaring that freedom has failed and stronger controls are necessary." --Ayn Rand
Dave,
in your first example with
I could not get the extra 10
I am using Dev-C++ and Windows XP
in your first example with
C++ Syntax (Toggle Plain Text)
while ( !file.eof() ) // bad!!
I am using Dev-C++ and Windows XP
May 'the Google' be with you!
![]() |
Similar Threads
- Timesaving Tips (C++)
- Response to time saving tips sticky (C++)
Other Threads in the C++ Forum
- Previous Thread: not sure why program crashes
- Next Thread: helpppppp me with this program
| Thread Tools | Search this Thread |
api array based binary bitmap business c++ c/c++ char class classes code coding commentinghelp compile console conversion count decide delete deploy desktop developer directshow dll download dynamic dynamiccharacterarray email encryption error faq file forms free fstream function functions game givemetehcodez graph guess gui hash homeworkhelp homeworkhelper iamthwee ifpug ifstream incrementoperators infinite input int integer java lib linkedlist linker listing loop looping loops map math matrix memory multiple news node output parameter pointer problem proficiency program programming project python random read recursion reference rpg string strings temperature template test text text-file tree url variable vector video win32 windows winsock wordfrequency wxwidgets





