Почему string — это char*?
Я так понял, что std::string не имелся в виду.
То есть суть вопроса такова: почему строки передают как char*, хотя это тип указателя на один char.
Дело в том, что массивы в C нельзя передавать как параметр функции, указатель на массив нельзя сохранить.
В результате массив, например char[8], принято передавать как указатель на его первый элемент: char*. Более того, при передаче массива в функцию он автоматически разлагается (decays) до указателя на первый элемент.
Остальные элементы получаются при помощи адресной арифметики: *(p+3) или p[3], что одно и то же. Итак, указатель в коде C может указывать как на одну переменную, так и на целый массив (точнее, его начало).
Для массивов int или любого другого типа обычно вместе с указателем на первый элемент передают размер массива. Но строки C завершаются нулевым символом, поэтому здесь длина известна и так. Вот и получается, что char* используют вместо char[N].
Edit: На самом деле, в C можно объявить указатель на массив:int (*arr)[10] = malloc(sizeof(*arr) * 5);
Не помню, чтобы я видел такую конструкцию в реальном коде.
Ох, только матчасть