В первой строке неявно объявляются 2 массива char'ов, содержащие "111" и "222" соотв., а затем явно - массив указателей на них (char* str[2]).
Во второй строке в функцию cout передается просто-напросто первый указатель, зачем было городить огород с взятием адреса указателя и затем переходом по нему, в итоге получая тот же самый указатель? Мог бы написать сразу cout << str[0] << endl; Если в cout передаешь указатель на char (char*), она будет шпарить по нему, увеличивая адрес, до тех пор, пока не наткнется на нулевой байт - признак конца строки. Поэтому выводится вся строка.
В третьей строке в функцию передается 0 символ '1' (простой char), благодаря операции перехода по указателю str[0]. Вот и выводится только 1 char.
хм, я ж вроде писал уже)) функции ввода-вывода вообще работают со строками только посредством указателей, если тому же cout'у передать char*, он и выведет строку по этому указателю. Точно так же если напишешь printf("%s",str[0]); - тоже получишь на консоль всю строку. Нужен адрес - без проблем, пишешь: cout << (int)(str[0]) << endl; - интерпретируешь аргумент как int, cout соответственно int и выдаст)) напишешь cout << "Mazafaka" << endl; - вызов будет проинтерпретирован как cout << (const char*)somearray << endl;