Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> указатель на строку 
:(
    Опции темы
LiRienko
Дата 10.9.2014, 11:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 10.9.2014

Репутация: нет
Всего: нет



Подскажите мне пожалуйста, насколько правильно определять указатель на строку таким образом:

Код

char* pStr = "First string!";
;

Или все-таки лучше определять указатель на строку так
Код

char* pStr = new char [strlen("First string!")];
strcpy(pStr, "First string!");
;
PM MAIL WWW   Вверх
feodorv
Дата 10.9.2014, 11:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 12
Всего: 45



Цитата(LiRienko @  10.9.2014,  12:28 Найти цитируемый пост)
насколько правильно определять указатель на строку таким образом

Все зависит от того, что вы с этой строкой будете делать. Если собираетесь ее менять, то первый вариант никак не подходит:
Цитата(LiRienko @  10.9.2014,  12:28 Найти цитируемый пост)
const char* pStr = "First string!";
Потому что область памяти, которая будет содержать в себе строку "First string!", будет доступна (скорее всего) только для чтения. Запись в неё приведет к краху программы.


Второй вариант:
Цитата(LiRienko @  10.9.2014,  12:28 Найти цитируемый пост)
char* pStr = new char [strlen("First string!")+1];
strcpy(pStr, "First string!");

возможен, но какой-то он корявый. Почему не просто:
Код

char pStr[] = "First string!";

И высвобождать память потом не понадобится. Если потом собираетесь менять содержимое pStr, то всегда нужно помнить, что под строку "First string!" отведено ограниченное число байт.


Если же строка не будет меняться, то первый вариант (с учетом const) вполне подходит.


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
kemiisto
  Дата 10.9.2014, 11:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дикий Кот. =^.^=
****
Награды: 1



Профиль
Группа: Участник Клуба
Сообщений: 3292
Регистрация: 29.7.2007

Репутация: 5
Всего: 160



Так, ну, судя по new это C++. Со строками в С++ надо работать посредством класса std::string cтандартной библиотеки. Сишечные извращения оставьте сишникам. smile 

Это сообщение отредактировал(а) kemiisto - 10.9.2014, 11:41


--------------------
PM MAIL WWW GTalk Jabber   Вверх
LiRienko
Дата 10.9.2014, 11:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 10.9.2014

Репутация: нет
Всего: нет



Цитата

Все зависит от того, что вы с этой строкой будете делать.


А если есть допустим такая задача: Написать свою функцию для объединения  двух строк.

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

Наверное тут лучше использовать указатели на строки, передать их в свою функцию. В ней перевыделить память для первой строки, дописать в нее вторую и вернуть указатель на этот новый участок памяти.

Добавлено через 2 минуты и 53 секунды
Вот к примеру 
Код

#include <iostream>
#include <cstring>
using namespace std;
 
char* giveNewMem(char *pstr1, int reqSize);
 
int main()
{
    setlocale(LC_ALL, "rus");
 
    int strSize1 = strlen("строка 1 ") + 1;
    int strSize2 = strlen("+ строка 2") + 1;
    
    char* pStr1 = new char[strSize1];
    strcpy_s(pStr1, strSize1, "строка 1 ");
        
    char* pStr2 = new char[strSize2];
    strcpy_s(pStr2, strSize2, "+ строка 2");
 
    cout << "1)" << pStr1 << endl;
    cout << "2)" << pStr2 << endl << endl;
 
    cout << "pStr1 занимает " << strSize1 << " байт памяти c \\0" << endl;
    cout << "pStr2 занимает " << strSize2 << " байт памяти c \\0" << endl;
 
    // strcat_s(pStr1, strSize1, pStr2); // НЕПРАВИЛЬНО! НЕДОСТАТОЧНО ПАМЯТИ В pStr1
    
    int requiredSize = (strSize1 + strSize2) - 1;
    cout << "\nНеобходимо " << requiredSize << " байт памяти для объединения строк." << endl << endl;
 
    pStr1 = giveNewMem(pStr1, requiredSize); //функция, которая перевыделит память
    
    strcat_s(pStr1, requiredSize, pStr2);
    cout << "pStr1: " << pStr1 << endl << endl;
    
    delete[] pStr1; // освобождаем память, которая была перевыделена в функции для strInFunc 
    delete[] pStr2; // освобождаем память, которая была выделена в main 
 
    return 0;
}
 
char* giveNewMem(char *pstr1, int reqSize)
{
    char* strInFunc = new char[reqSize]; // для копирования строки pstr1 перед удалением памяти
    
    strcpy_s(strInFunc, reqSize, pstr1);
        
    delete [] pstr1; // освобождаем память pstr1
 
    return strInFunc;
}

PM MAIL WWW   Вверх
math64
Дата 10.9.2014, 12:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



Ну тогда стоит добавить функцию для первоначального выделения памяти:
Код

char* giveFirstMem(const char *pstr1, int& reqSize)
{
    reqSize = strlen(pstr1) + 1;
    char* strInFunc = new char[reqSize]; // для копирования строки pstr1
    
    strcpy_s(strInFunc, reqSize, pstr1);
        
    return strInFunc;
}

int strSize1;
char* pStr1 = giveFirstMem("строка 1 ", strSize1);

Но лучше пользоваться std::string, как советовал kemiisto, QString если пользуете Qt и т.п.
PM   Вверх
feodorv
Дата 10.9.2014, 12:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 12
Всего: 45



Цитата(LiRienko @  10.9.2014,  12:55 Найти цитируемый пост)
    int strSize1 = strlen("строка 1 ") + 1;
    int strSize2 = strlen("+ строка 2") + 1;
    
    char* pStr1 = new char[strSize1];
    strcpy_s(pStr1, strSize1, "строка 1 ");
        
    char* pStr2 = new char[strSize2];
    strcpy_s(pStr2, strSize2, "+ строка 2");

Честно говоря, я в таком коде смысла не вижу. Вам даже приходится дважды упоминать один и тот же текст строк.


В приведенном коде Вы первоначальные строки не меняете. Соответственно, можно позволить себе:
Код

const char *pStr1 = "строка 1 ";
const char *pStr2 = "+ строка 2";
char *cStr = concatenatetwo( pStr1, pStr2);



Цитата(LiRienko @  10.9.2014,  12:55 Найти цитируемый пост)
В ней перевыделить память для первой строки, дописать в нее вторую и вернуть указатель на этот новый участок памяти.

Это лишние телодвижения, которые вдобавок предполагают, что у Вас строки аллоцированные. А если нет? Я теперь не могу делать так:
Код
concatenatetwo( "Output: ", string);
??? За что?)))


Самое простое решение:
Код

char *concatenatetwo( const char *pStr1, const char *pstr2)
{
  size_t len1 = strlen(pStr1);
  size_t len = len1 + strlen(pstr2) + 1;
  char *cStr = new char[len];
  strcpy( cStr, pStr1);
  strcpy( &cStr[len1], pStr2);
  return cStr;
}

Здесь есть, конечно, что пооптимизировать и добавить, но идея, мне кажется, ясна.


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
LiRienko
Дата 10.9.2014, 14:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 10.9.2014

Репутация: нет
Всего: нет



Спасибо всем за участие в этом обсуждении. Главное, что мне стало понятно - это то, что ничего страшного в указателях на строковую константу нет
 
Код

const char *pStr1 = "строка 1 ";
const char *pStr2 = "+ строка 2";


 и их можно спокойно применять в программе )))

А чтобы объединить такие строки, лучше объявить отдельный указатель и присвоить ему значение (адрес), которое вернет функция, объединяющая две строки.  smile 


PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0918 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.