2012-07-05 2 views
-1

Указатели всегда делали меня пустой о логике, которую я намерен использовать в коде, если кто-то может помочь мне понять несколько концепций, которые были бы действительно полезными. Вот фрагмент кода из моей программы,Указатели на C++ - дилемма новичка

vector <char> st; 
char *formatForHtml(string str, string htmlTag) 
{ 
    string strBegin; 
    strBegin = "<"; 
    strBegin.append(htmlTag); 
    strBegin.append(">"); 
    strBegin.append(str); 
    string strEnd = "</"; 
    strEnd.append(htmlTag); 
    strEnd.append(">"); 
    strBegin.append(strEnd); 
    st.resize(strBegin.size()); 
    for (int i =0;i <strBegin.size();i++) { 
     st[i] = strBegin.at(i); 
    } 
    return &st[0]; 
} 

В коде выше, если я должен вернуться адрес st[0], я должен написать функцию типа char *. Мне нужно знать причину этого, также, если адрес является целым значением, почему я не могу определить функцию как тип int?

P.S. Это сомнение в уровне начинающих.

+2

Что' ул. '????? –

+0

См. Также этот вопрос [Может ли доступ локальной памяти к внешней области?] (Http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed вне его сферы) –

+0

@ LuchianGrigore Plz см. edit – vin

ответ

0

Я должен написать функцию типа «символ *» Мне нужно знать причину, чтобы сделать так

Там нет причин, чтобы сделать это. Просто верните std::string.

С точки зрения вашего кода st является std::vector<char>. Поскольку std::vector имеет непрерывную память, &st[0] - это адрес первого char в векторе и, следовательно, указывает на не строку с нулевым символом, которую вектор представляет, что не очень полезно вне функции, потому что вы не можете найти длина.

+0

Мне нравится ваше первое предложение. Он говорит это наиболее кратко: никогда, как я вижу, никогда не было причины возвращать символ. (Могут быть случаи, когда «char const *» оправдан. Но даже те редкие и, вероятно, не представляют интереса, кроме эксперта.) –

+0

@Luchian. Длина здесь не является важным фактором, все, что мне нужно знать, это , Возможно ли вернуть адрес 'st [0]' без определения функции как 'char *'. – vin

+0

@vin, не определяя его как 'char *', вы можете вернуть строку и сделать так, как было предложено.В противном случае я не вижу никакой пользы (вместо этого вы можете вернуть 'void *', но не делайте этого). –

0

Это неудобный код, вы ожидаете «str» в качестве аргумента, но затем вы возвращаете его ячейку памяти? Почему бы не вернуть строку?

В вашем коде имеется несколько опечаток. (Вы имели в виду «str», когда вы набрали «st»? Если нет, то где «st» определено?)

Что касается того, почему вы не можете определить функцию как тип «int», «int» - это другой тип «указатель на символ».

Лично я бы вернул «строку» и просто получил «return str» в конце.

+0

Он возвращает 'st', а не' str'. –

+0

@ Luchian: Вы комментируете * путь * слишком быстро! :) – Arafangion

0

Указатель - это указатель, а не целое значение. Код прав тогда и только тогда, когда st - глобальная переменная или объявлена ​​как статическая в этой функции. Но возвращаемая строка предпочтительно, чем возвращаемый указатель.

+0

st - глобальная переменная, см. Редактирование. – vin

0

Простой.

string str 

- это что-то, что содержит кучу символов.

str[0] 

возвращение первого символа.

Поэтому

&str[0] 

дает адрес первого символа, поэтому это «символ *» --- «символ» является то, что указатель указывает на «*» является «адрес "часть указателя. Тип указателя относится к объекту, на который указывают.

Кроме того, адреса могут быть только «целыми» на аппаратном уровне (все является целым числом ... кроме самих целых чисел, они представляют собой кучу bools), но это ничего не значит для языка более высокого уровня , Для языка более высокого уровня указатель - это указатель, а не целое число.

Рассмотрение одного как другого почти всегда является ошибкой, а C++ 11 даже добавил ключевое слово nullptr, поэтому нам не нужно полагаться на один действительный случай «указатель - целочисленный».

И, кстати, ваш код не будет работать. «str» существует только для продолжительности функции, поэтому, когда функция возвращает «str», перестает существовать, что означает, что указатель, который вы вернули, указывает на большой черный нигде.

+0

\ * ... \ * - команда форматирования уценки. Вместо этого вы можете использовать \ \ *. – Chowlett

0

Почему бы вам не использовать строку как возвращаемый тип для вашей функции?

Первый: указатель - это что-то, лежащее в памяти, поэтому вы не можете заменить его целым числом (только с некоторыми грязными трюками).

Второй: & Адрес [0] - это адрес внутреннего буфера, который использует строка для хранения его содержимого. Когда st выходит за пределы области (или используется повторно для следующего вызова), она будет перезаписана или возвращена менеджеру кучи, поэтому вызов, вызывающий эту функцию, закончится каким-то мусором.

Btw, большая часть вашей функции делает ненужную работу, которую класс строк может выполнять сам по себе (например, копирование strBegin на st).

1

Вы не сообщите нам, что такое st, поэтому мы не можем определить, является ли код совершенно неправильным, или просто плохим дизайном. Если st опечатка для str (только угадывать, так как str нигде не используется), то у вас есть неопределенного поведения, и программа является неправильной, так как вы возвращением указателя на объект, который был деградировавшим. Во всяком случае, функция , такая как formatForHtml, должна вернуть std::string, как значение , а не указатель (и, конечно, не указатель на неконстантный).

Я могу добавить, что вы не используете цикл для копирования символа строковых значений на символ . std::string действует как обычный тип значения, поэтому вы можете просто назначить: st = strBegin;.

EDIT:

Просто для записи, я с тех пор пересмотрел свой код. Естественный путь писать его не будет:

std::string 
formatForHtml(std::string const& cdata, std::string const& tag) 
{ 
    return '<' + tag + '>' + cdata + "</" + tag + '>'; 
} 

Нет указателей (по крайней мере, не видно --- на самом деле, «+ оператор), и полное использование std::string сек объектов

+0

См. Изменение в коде. – vin

+0

@vin 'std :: string tmp = '<' + tag + '>' + cdata +"'; st.assign (tmp.begin(), tmp.end()); ' –

Смежные вопросы