#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;
}
Saturday, March 27, 2010
Objective-C. Convert C-style string to NSString and vice versa
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.
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).
Here is an answer:
http://lists.apple.com/archives/xcode-users/2009/Oct/msg00616.html
#include <iostream>It happens only in the debug mode:
#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;
}
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.
I've never thought about the programming in this way. But it is really so.
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:
A bit more interesting program:
#include <iostream>Here is the output in the console:
#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;
}
Program loaded.
run
[Switching to process 295]
Running…
6 8 10 12 4 6
Debugger stopped.
Program exited with status value:0.
#include <iostream>The output:
#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;
}
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:
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:
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:[Session started at 2010-03-11 22:26:59 +0200.]2010-03-11 22:27:00.008 Enumerator[4905:903] foo2010-03-11 22:27:00.014 Enumerator[4905:903] barThe Debugger has exited with status 0.
#import <Foundation/Foundation.h>Same with NSArray:
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;
}
#import <Foundation/Foundation.h>And with the for..in loop:
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;
}
#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:
Here is the console window:
[Session started at 2010-03-11 21:04:18 +0200.]
#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:
More interesting practical use of the output iterators is the STL copy algorithm:
#include <iostream>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.
#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;
}
More interesting practical use of the output iterators is the STL copy algorithm:
#include <iostream>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:
#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;
}
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:
The following program shows the return values from these operators:
It behaves exactly as the built-in types:
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:
For input iterator postfix ++ operation means to step forward and return old position, the prefix ++ also means to step forward and return new position.
#include <iostream>The program output is:
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;
}
[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>Here is the program output:
#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;
}
[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>Postfix ++ is allows to get the next input value.
#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;
}
For input iterator postfix ++ operation means to step forward and return old position, the prefix ++ also means to step forward and return new position.
Subscribe to:
Posts (Atom)