Pages

Saturday, March 27, 2010

Objective-C. Convert C-style string to NSString and vice versa

#import <Foundation/Foundation.h>

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

// Standard C-style string
const char *foo = "Hello, World!";

// Create NSString from a C string
NSString *bar = [NSString stringWithUTF8String:foo];

// Create a C string from an NSString
foo = [bar UTF8String];

[pool drain];
return 0;
}

Objective-C. Sample with comments

Here is a simple Objective-C program where almost all lines have comments:
// the following directive import is the same as include but it ensures
// that the file is included only once.
//
// The following line includes the headers for all the classes in
// the Foundation framework. The headers are precompiled, so this
// approach is not as computationally intensive as it sounds.
#import <Foundation/Foundation.h>

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

// Variable array is declared here. It is a pointer to an instance
// of NSMutableArray. Note that no array exists yet.
NSMutableArray *array;

//Here the array is created.
array = [[NSMutableArray alloc] init];
int i;
for (i = 0; i < 10; i++)
{
NSNumber *newNumber = [[NSNumber alloc] initWithInt:(i * 3)];

// The array does not make copies of the NSNumber objects.
// Instead it simply keeps a list of pointers to the
// NSNumber objects.
[array addObject:newNumber];
}

for (i = 0; i < 10; i++)
{
NSNumber *numberToPrint = [array objectAtIndex:i];
// %@ - the object gets send the message description,
// and the string it returns replaces %@ in the string.
NSLog(@"The number at index %d is %@", i, numberToPrint);
}

[pool drain];
return 0;
}

Tom Love

Tom Love, Ph.D., is the author (with Brad Cox) of Objective-C language. Now he's Co-Founder and CEO of Shoulders Corp.

Friday, March 26, 2010

Brad Cox

Brad Cox, Ph.D. in mathematical biology, the author of Objective-C.
Objective-C is an extension of the C language. In fact, Objective-C originally was a C preprocessor and a library. Brad Cox added Smalltalk-like classes and message-sending mechanism to he powerful C programming language.

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.

Monday, March 8, 2010

Parse the text with integer values

Simply a kind of an interesting task: retrieve all integer values from a string like "10 223 21 67"
#include <stdio.h>
#include <string.h>

int main (int argc, const char * argv[])
{
char strInts[] = "10 223 21 67";
char delim[] = " ";
char *token;
int i;
token = strtok(strInts, delim);
while( token != NULL )
{
sscanf(token, "%d", &i);
printf("%d\n",i);

token = strtok( NULL, delim );
}

return 0;
}

Sunday, March 7, 2010

Postfix ++. Prefix++

Class Digit in the following program has operator++ implemented in the prefix and postfix forms:
#include <iostream>
using namespace std;

class Digit {
int value;

public:
Digit() : value(0) {}
Digit(const Digit& digit)
{
value = digit.value;
}

//prefix ++
Digit& operator++ ()
{
if (value > 8)
value = 0;
else
value++;
return *this;
}

//postfix ++
Digit operator++(int)
{
Digit digit = *this;
++*this;
return digit;
}

int Value() { return value; }
};

int main (int argc, char * const argv[])
{
Digit digit;
cout << "initially: digit = " << digit.Value() << endl;
digit++;
cout << "postfix ++: digit = " << digit.Value() << endl;
++digit;
cout << "prefix ++: digit = " << digit.Value() << endl;

return 0;
}
The program output is:

[Session started at 2010-03-07 21:38:52 +0200.]
initially:  digit = 0
postfix ++: digit = 1
prefix ++:  digit = 2
The Debugger has exited with status 0.

The following program shows the return values from these operators:
int main (int argc, char * const argv[]) 
{
Digit digit1, digit2;
cout << "initially digit1 = " << digit1.Value() << endl;
cout << " digit2 = " << digit2.Value() << endl;
digit2 = digit1++;
cout << "postfix ++: digit1 = " << digit1.Value() << endl;
cout << " digit2 = " << digit2.Value() << endl;
digit2 = ++digit1;
cout << "prefix ++: digit1 = " << digit1.Value() << endl;
cout << " digit2 = " << digit2.Value() << endl;

return 0;
}

[Session started at 2010-03-08 23:48:15 +0200.]
initially  digit1 = 0
           digit2 = 0
postfix ++: digit1 = 1
            digit2 = 0
prefix ++:  digit1 = 2
            digit2 = 2

The Debugger has exited with status 0.

It behaves exactly as the built-in types:
#include <iostream>

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

int x = 0;
int y = x++;
std::cout << "x = " << x << std::endl;
std::cout << "y = " << y << std::endl;

return 0;
}


run
[Switching to process 813]
Running…
x = 1
y = 0

Debugger stopped.
Program exited with status value:0.


This code (with minor changes) was taken from:
Overloading the increment and decrement operators

The main trick is a fake integer parameter for the postfix operator - it allows to distinguish the postfix and prefix versions. The postfix and prefix operators return different values - the prefix operator return the object after it has been incremented. The postfix operator returns the value before it was incremented.
So it makes sense to prefer prefix operator (preincrement), because it might performs better. The preincrement operator does not have to return the old value that must be stored in a temporary object.

"C++ Std ISO IEC 9899 1990" says about the prefix and postfix operators:

5.2.6 Increment and decrement [expr.post.incr]
1 The value obtained by applying a postfix ++ is the value that the operand had before applying the operator. [Note: the value obtained is a copy of the original value ] The operand shall be a modifiable lvalue. The type of the operand shall be an arithmetic type or a pointer to a complete object type. After the result is noted, the value of the object is modified by adding 1 to it, unless the object is of type bool, in which case it is set to true. [Note: this use is deprecated, see annex D. ] The result is an rvalue. The type of the result is the cv-unqualified version of the type of the operand. See also 5.7 and 5.17.
2 The operand of postfix -- is decremented analogously to the postfix ++ operator, except that the operand shall not be of type bool. [Note: For prefix increment and decrement, see 5.3.2. ]
and below:
5.3.2 Increment and decrement [expr.pre.incr]
1 The operand of prefix ++ is modified by adding 1, or set to true if it is bool (this use is deprecated). The operand shall be a modifiable lvalue. The type of the operand shall be an arithmetic type or a pointer to a completely-defined object type. The value is the new value of the operand; it is an lvalue. If x is not of type bool, the expression ++x is equivalent to x+=1. [Note: see the discussions of addition (5.7) and assignment operators (5.17) for information on conversions. ]
2 The operand of prefix -- is modified by substracting 1. The operand shall not be of type bool. The requirements on the operand of prefix -- and the properties of its result are otherwise the same as those of prefix ++. [Note: For postfix increment and decrement, see 5.2.6. ]
The practical use of the prefix and postfix operator ++ (and maybe the most important) is the input iterators in STL. The following program finds an element in the list:
#include <iostream>
#include <list>

int main (int argc, char * const argv[]) {
int a[10] = { 15, 2, 56, 78, 89, 7, 16, 45, 7, 99 };
std::list<int> myList(&a[0], &a[10]);
std::list<int>::iterator it = std::find(myList.begin(), myList.end(), 7);
if (*it == 7)
std::cout << "7 found in the list" << std::endl;
return 0;
}
Here is the program output:

[Session started at 2010-03-08 23:37:06 +0200.]
7 found in the list

The Debugger has exited with status 0.
And here is a classical istream iterator, which is used to read values from the input stream:
#include <iostream>
#include <iterator>
using namespace std;

int main () {
double value1, value2;
cout << "Please, insert two values: ";

istream_iterator<double> eos; // end-of-stream iterator
istream_iterator<double> iit (cin); // stdin iterator

if (iit!=eos)
value1=*iit;

iit++;
if (iit!=eos)
value2=*iit;

cout << value1 << "*" << value2 << "=" << (value1*value2) << endl;

return 0;
}
Postfix ++ is allows to get the next input value.
For input iterator postfix ++ operation means to step forward and return old position, the prefix ++ also means to step forward and return new position.