Получение адреса строкового элемента из массива указателей, который содержит массивы указателей, которые содержат элементы адресной строки - PullRequest
0 голосов
/ 20 ноября 2018

'ptrArrMain' - массив указателей, который содержит два массива указателей (ptrArr1 и ptrArr2).У меня есть строка ab = "ab".Адрес ab [1] (т.е. адрес «b») хранится в элементе ptrArr1 [1].ptrArr1 [0] (т. е. адрес 'a') назначен для ptrArrMain [0].

Как получить адрес ab [1], используя только массив ptrArrMain?Я не хочу использовать какие-либо STL или предварительно закодированные функции.Я делаю это упражнение, чтобы улучшить мое понимание указателей.Спасибо.

int main()
{

    string ab = "ab";
    string cd = "cd";

    char **ptrArrMain = new char*[2];
    char **ptrArr1 = new char*[ab.length()];
    char **ptrArr2 = new char*[cd.length()];

    ptrArr1[0] = &ab[0];
    ptrArr1[1] = &ab[1];

    ptrArr2[0] = &cd[0];
    ptrArr2[1] = &cd[1];

    ptrArrMain[0] = ptrArr1[0];
    ptrArrMain[1] = ptrArr2[0];

    cout << &ab[1] << endl;

    //  TODO
    //  Get the address of ab[1] using 'ptrArrMain'. 
    //  Do not use any other array.*/

}

Я думаю, что это должно быть возможно, потому что ptrArrMain [0] содержит адрес первого элемента "ab".С помощью адреса первого элемента «ab» я смогу получить адрес ab [1], увеличив (или каким-либо другим способом) адрес ab [0], который находится в ptrArrMain [0].

1 Ответ

0 голосов
/ 20 ноября 2018

Когда я запускаю ваш текущий код, используя директиву using namespace std и импортируя стандартные библиотеки iostream и string, я получаю следующий результат:

 > g++ test.cpp -o test
 > ./test
 b

Почему это так?Хорошо, если вы посмотрите на свой код, вы заметите, что ab имеет тип std :: string (который является стандартным типом библиотеки).В документации мы находим, что использование оператора [] в строке на самом деле является перегруженной операцией (т. Е. Она вызывает метод), которая возвращает ссылку на символ . Если вы попытаетесь получить адрес ссылки, вы получите саму ссылку , поэтому печатается b.

Если вы хотите получить адреса базовых строк, выследует использовать строки в стиле C он же символьные массивы.Затем вы можете получить доступ к базовым массивам, используя индексы массива или арифметику указателей .

    char ab[3] = "ab";
char cd[3] = "cd";

char **ptrArrMain = new char*[2];
char **ptrArr1 = new char*[strlen(ab)];
char **ptrArr2 = new char*[strlen(cd)];

ptrArr1[0] = &ab[0];
ptrArr1[1] = &ab[1];

ptrArr2[0] = &cd[0];
ptrArr2[1] = &cd[1];

ptrArrMain[0] = ptrArr1[0];
ptrArrMain[1] = ptrArr2[0];


cout << (void *)&ab[1]  << endl;
cout << (void *)(ptrArrMain[0] + 1) << endl;
cout << (void *)(*ptrArrMain + sizeof(char)) << endl;

, которые будут выводить 3 идентичных адреса памяти.

Вы также должны быть осторожны при печати адресовстрок как cout будет интерпретировать их как сами строки .

...