Pages

Sunday, March 21, 2010

Xcode 3.2.1. gcc 4.2 stringstream.

This classical code does not work in Xcode 3.2 (gcc 4.2).
#include <iostream>
#include <sstream>
using namespace std;

int main (int argc, char * const argv[])
{
int x = 9;
stringstream ss;
ss << x;
cout << "x = " << ss.str() << endl;

return 0;
}
It happens only in the debug mode:

Program loaded.
run
[Switching to process 4719]
Running…
x = 

Debugger stopped.
Program exited with status value:0.
In release everything's fine:

Program loaded.
run
[Switching to process 4768]
Running…
x = 9

Debugger stopped.
Program exited with status value:0.


Here is an answer:
http://lists.apple.com/archives/xcode-users/2009/Oct/msg00616.html

Friday, March 19, 2010

The Key Concept of OOP is Indirection

I found an interesting introduction to OOP in an Objective-C book:
Mark Dalrymple, Scott Knaste. Learn Objective–C on the Mac.
An old saying in programming goes something like this, “There is no problem in computer science that can’t be solved by adding another level of indirection.” Indirection is a fancy word with a simple meaning—instead of using a value directly in your code, use a pointer to the value. Here’s a real-word example: you might not know the phone number of your favor- ite pizza place, but you know that you can look in the phone book to find it. Using the phone book like this is a form of indirection.
Indirection can also mean that you ask another person to do something rather than doing it yourself...

I've never thought about the programming in this way. But it is really so.

Thursday, March 18, 2010

STL. Transform

Here is a simple program using transform algorithm:
#include <iostream>
#include <algorithm>
#include <iterator>
using namespace std;

int sum(int n, int m) { return (n + m); }

int main (int argc, char * const argv[]) {

int i1[] = { 0, 1, 2, 3, 4, 5 };
int i2[] = { 6, 7, 8, 9, 0, 1 };

ostream_iterator<int> out(cout, " ");
transform(&i1[0], &i1[6], &i2[0], out, sum);
return 0;
}
Here is the output in the console:

Program loaded.
run
[Switching to process 295]
Running…
6 8 10 12 4 6 
Debugger stopped.
Program exited with status value:0.

A bit more interesting program:
#include <iostream>
#include <algorithm>
#include <iterator>
#include <vector>
#include <string>
using namespace std;

string makeFullName(string& str1, string& str2)
{
return str1 + " " + str2;
}

int main (int argc, char * const argv[]) {
vector<string> first;
vector<string> second;

first.push_back("George");
first.push_back("Pavel");
first.push_back("Ivan");

second.push_back("Reznik");
second.push_back("Bush");
second.push_back("Ivanov");

ostream_iterator<string> out(cout, ", ");
transform(first.begin(), first.end(), second.begin(), out, makeFullName);


return 0;
}
The output:

Program loaded.
run
[Switching to process 395]
Running…
George Reznik, Pavel Bush, Ivan Ivanov, 
Debugger stopped.
Program exited with status value:0.

Thursday, March 11, 2010

Loop For

Today I found a wonderful blog: Able Pear Software. Here is first two posts I read there:
1. Objective-C Tuesdays: The for loop
2. Objective-C Tuesdays: for loop variations
Sure, the subject is trivial. But the explanation is perfect. Simple and clear.
Next tutorial Objective-C Tuesdays: The for...in loop shows new things. For example, the following program uses an enumerator to print out the elements of NSSet:
#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

NSSet *items = [NSSet setWithObjects:@"foo", @"bar", nil];
NSEnumerator *enumerator = [items objectEnumerator];
NSString *item = nil;
while (item = [enumerator nextObject]) {
NSLog(item);
}

[pool drain];
return 0;
}
The program output looks so:
[Session started at 2010-03-11 22:26:59 +0200.]
2010-03-11 22:27:00.008 Enumerator[4905:903] foo
2010-03-11 22:27:00.014 Enumerator[4905:903] bar

The Debugger has exited with status 0.
For NSArray it is obviously to use for-loop. NSSet does not have a well defined order, so NSEnumerator used to be the only option. Now, the same task can be solved with for..in-loop:
#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

NSSet *items = [NSSet setWithObjects:@"foo", @"bar", nil];
NSString *item = nil;
for (item in items) {
NSLog(@"item = %@", item);
}

[pool drain];
return 0;
}
Same with NSArray:
#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

NSArray *collection = [NSArray
arrayWithObjects:@"foo", @"a", @"bar", @"baz", nil];
for (NSUInteger i = 0; i < collection.count; i++) {
NSString *item = [collection objectAtIndex:i];
NSLog(@"item '%@'", item);
}
[pool drain];
return 0;
}
And with the for..in loop:
#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

NSArray *collection = [NSArray
arrayWithObjects:@"foo", @"a", @"bar", @"baz", nil];
for (NSString *item in collection) {
NSLog(@"item '%@'", item);
}
[pool drain];
return 0;
}

Print float number

The following program prints a float number in different formats:
#include <iostream>
using namespace std;

int main (int argc, char * const argv[]) {
float number = 123.456;

cout << "number in fixed form = " << number << endl; //default is fixed
cout << "number in scientific form = " << scientific << number << endl;
cout.precision(2);
cout << "number in fixed form with precision 2 = " << fixed << number << endl;
cout.precision(3);
cout << "number in fixed form with precision 3 = " << number << endl;
cout.precision(4);
cout << "number in fixed form with precision 4 = " << number << endl;
cout.precision(5);
cout << "number in fixed form with precision 5 = " << number << endl;

return 0;
}

Here is the console window:

[Session started at 2010-03-11 21:04:18 +0200.]
number in fixed form = 123.456
number in scientific form = 1.234560e+02
number in fixed form with precision 2 = 123.46
number in fixed form with precision 3 = 123.456
number in fixed form with precision 4 = 123.4560
number in fixed form with precision 5 = 123.45600

The Debugger has exited with status 0.


Wednesday, March 10, 2010

Hexadecimal Output


#include <iostream>
#include <vector>
using namespace std;

void print(int c)
{
cout << "0x" << hex << c << " ";
}

int main (int argc, char * const argv[])
{
char a[8] = { 'a', 'b', 'c', '1', '2', '3', 'z', 'y' };
vector<char> v(&a[0], &a[8]);
for_each(v.begin(), v.end(), print);
return 0;
}

Output:



[Session started at 2010-03-10 21:02:22 +0200.]
0x61 0x62 0x63 0x31 0x32 0x33 0x7a 0x79 
The Debugger has exited with status 0.



Or "Hello, World!":
#include <iostream>
#include <vector>
using namespace std;

void print(int c)
{
cout << "0x" << uppercase << hex << c << " ";
}

int main (int argc, char * const argv[]) {
char* str = "Hello, World!";
vector<char> v(&str[0], &str[strlen(str)]);
for_each(v.begin(), v.end(), print);
return 0;
}

[Session started at 2010-03-10 21:23:06 +0200.]

0x48 0x65 0x6C 0x6C 0x6F 0x2C 0x20 0x57 0x6F 0x72 0x6C 0x64 0x21 

The Debugger has exited with status 0.

Classical Output Iterator

Output iterator allow to write values into a sequence. The classical output iterator is ostream iterator, which is used to write values to the output stream:
#include <iostream>
#include <iterator>
#include <list>

int main (int argc, char * const argv[]) {
int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };

std::copy(&a[0], &a[10], &b[0]);

std::ostream_iterator<int> out(std::cout, " ");
std::copy(&a[0], &a[10], out);

std::cout << "\n";

return 0;
}
Output iterator allows to write value. For example if first is an output iterator, we can use *first=..., but it is not guarantee that we can obtain the value if will use *first.
More interesting practical use of the output iterators is the STL copy algorithm:
#include <iostream>
#include <iterator>
#include <list>

int main (int argc, char * const argv[]) {
int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
int b[10];

std::copy(&a[0], &a[10], &b[0]);
std::list<int> myList(&a[0], &a[10]);

std::ostream_iterator<int> out(std::cout, " ");
std::copy(myList.begin(), myList.end(), out);
std::cout << "\n";

return 0;
}
This program above copies an array a ino array b, then into a list. In the end, the list is copied into the output stream:

Loading program into debugger…
Program loaded.
run
[Switching to process 2192]
Running…
1 2 3 4 5 6 7 8 9 0 

Debugger stopped.
Program exited with status value:0.