Указатель не только для чтения. (сами строковые данные есть, но указатель, указывающий на них, может быть свободно изменен). Однако назначение символа указателю не дает ожидаемого результата.
В общем, единственное, что вы можете назначить точке - это адрес. Вы не можете назначать значения, только адрес значений.
Строковые литералы (например, "hello world") являются единственным исключением, потому что строки являются специальными. Если вы назначите один из них указателю, вы получите указатель на эту строку. Но в целом вы назначаете адреса указателям.
Другой момент заключается в том, что символы в C ++ являются целочисленными типами данных. Они могут рассматриваться как целые числа без использования приведения.
Я могу сделать int i = 'W'
, и компилятор не будет жаловаться.
Так что же произойдет, если вы назначите 'W' указателю? Он принимает «W» в качестве целочисленного значения и предполагает, что это адрес. «W» имеет значение ASCII 127, поэтому вы фактически устанавливаете указатель на указатель на адрес 127, что не имеет смысла.
Я не понимаю, как это связано с вашим кодом.
Кажется, проблема в том, что temp
не указывает на действительные данные. Вы объявляете указатель, который указывает на какой-то неопределенный адрес. И затем вы говорите: «Где бы это ни указывало, я хочу записать значение, на которое указывает s
. Следующее должно работать несколько лучше:
char temp; // not a pointer. We want a character to store our temporary value in
while (s <= e) {
temp = *s; // note, no * on temp.
*s = *e;
*e = temp; // note, no * on temp.
e--;
s++;
}
Однако, если str
указывает на строковый литерал, например «hello world», то это будет недопустимо, поскольку сами строковые данные доступны только для чтения. Компилятор может не применять его, но тогда вы рискуете попасть в страну неопределенного поведения. Если вы хотите изменить строку, скопируйте ее в локальный буфер, как показал один из других ответов.
Вы, кажется, немного озадачены семантикой указателей. Присвоение адреса (или чего-то, что может быть преобразовано в адрес, например целое число) указателю делает указатель указателем на этот адрес. Он не изменяет указанные данные.
Объявление указателя не означает, что он будет указывать на что-либо значимое. Если вы хотите сохранить char, объявите переменную char. Указатель не хранит данные, он просто указывает на данные, размещенные в другом месте.
редактировать
Комментарии и исправления к вашему обновленному коду:
void something(const char * str) { // let the function take a pointer to a non-modifiable string, so add the const. Now it's clear that we're not allowed to modify the string itself, so we have to make a copy.
char *s = new char[strlen(str) + 1]; // Since the original string is const, we have to allocate a copy if we want to modify it - in C, you'd use malloc(strlen(str)) instead
strcpy(s, str);
char *e = s; // make e point to the start of the copied string (don't allocate two copies, since e and s are supposed to work on the same string
while (*e != '\0') { // add braces so it's clear where the loop starts and ends.
e++;
}
e--;
while (s <= e) { // the loop condition wouldn't work if s and e pointed to separate copies of the string
cout << *e; // why? I thought you just wanted to reverse the string in memory. Alternatively, if you just want to print out the string reversed, you don't need to do most of the rest of the loop body. In C, you'd use printf instead of *e
char temp = *s; // might as well declare the temp variable when you need it, and not before
*s = *e;
*e = temp;
e--;
s++;
}
}
Просто для справки, и в ответ на комментарии о C против C ++, вот как я написал бы функцию для обратного преобразования строки в C ++:
std::string revert_string(const std::string& str) {
return std::string(str.rbegin(), str.rend());
}
Или чтобы вернуть строку на место:
std::string revert_string(const std::string& str) {
std::reverse(str.begin(), str.end());
}