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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> не понемаю почему так. 
:(
    Опции темы
yngwie19
Дата 18.12.2008, 23:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 15.6.2008
Где: Новгород

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



Я что-то совсем запутался. Чем отличается присваивание:
Код

char *ptr;
ptr = "name";

от 
Код

char ptr[10];
ptr = "name";


Почему в первом случае нет ошибок, Мне казалось, что присваивать строку указателю нельзя, однако все работает правильно.
Во втором случае понятно происходит ошибка, а почему певый работает?
Модератор: Название темы должно отражать ее суть!

Это сообщение отредактировал(а) bsa - 18.12.2008, 23:37
PM MAIL   Вверх
mes
Дата 18.12.2008, 23:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



потому что любое выражение в кавычках, вида "any" именуемое строкой, компилятор снабжает завершающим нулем и помешает в секцию данных,
а вместо него подставляет указатель типа (const) char * с адресом на этот участок памяти. 


Это сообщение отредактировал(а) mes - 18.12.2008, 23:45


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


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

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



char *ptr - это указатель на переменную типа char
char ptr[10] - это массив переменных типа char (ему нельзя присвоить указатель).
"name" - это строковый литерал. В твоем случае он представляется в виде константы типа const char *. По хорошему, присваивание не должно работать в обоих случаях (нельзя неконстантному указателю присвоить константный), но для строковых литералов было сделано исключение (для сохранения совместимости).

кстати, ты можешь написать так: char ptr[10] = "name" или даже так: char ptr[] = "name". И это будет работать. Более того, во втором случае будет создан массив необходимого для хранения указанной строки размера автоматически.

короче, пользуйся strcpy()
PM   Вверх
yngwie19
Дата 18.12.2008, 23:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 15.6.2008
Где: Новгород

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



mes, а почему тогда во втором случае ошибка, ведь ptr[10] это же есть указатель на первый элемент, т.е ptr.
PM MAIL   Вверх
mes
Дата 18.12.2008, 23:51 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



во втором случае массив, его можно заполнить таким образом только на этапе инициализации, как показал bsa.
массив можно привести к char*, но не наоборот, a использовать operator []  можно у обоих smile

Добавлено @ 23:57
Цитата(yngwie19 @  18.12.2008,  23:47 Найти цитируемый пост)
ведь ptr [10] это же есть указатель на первый элемент, т.е ptr. 

а попробуйте поменять этот указатель , анапример так: 
Код

char ptr [10];
++ptr;

то что переменная-массива является указателем на первый элемент, совсем не значит, что она и переменная-указатель это одно и то же.

Это сообщение отредактировал(а) mes - 18.12.2008, 23:58


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


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 15.6.2008
Где: Новгород

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



во втором случае Я не могу присвоить указатель на строку "name", т.к ptr[0] уже грубо говоря указывает на какой-то объект правильно?
PM MAIL   Вверх
mes
Дата 18.12.2008, 23:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(yngwie19 @  18.12.2008,  23:58 Найти цитируемый пост)
ptr[0] уже грубо говоря указывает на какой-то объект правильно? 

нет, потому что ptr не указатель 


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


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 15.6.2008
Где: Новгород

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



Цитата(bsa @  18.12.2008,  23:44 Найти цитируемый пост)
короче, пользуйся strcpy() 

но тогда нужно память виделять динамически (new/delete) не так ли?
PM MAIL   Вверх
mes
Дата 19.12.2008, 00:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



между
Код

char *p;
char ptr[10];
++p;
++ptr;


разница примерна такая же как и здесь :
Код

int i =5;
int f() { return 5; }
++i;
++f(); 


Цитата(yngwie19 @  19.12.2008,  00:00 Найти цитируемый пост)
но тогда нужно память виделять динамически (new/delete) не так ли? 

не так. зачем выделять еше если ты уже выделил достаточно сторкой ptr [10] ?
Код

char ptr [10];
strcpy (ptr, "name");


Это сообщение отредактировал(а) mes - 19.12.2008, 00:06


--------------------
PM MAIL WWW   Вверх
yngwie19
Дата 19.12.2008, 00:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 15.6.2008
Где: Новгород

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



mes, нет если просто объявлять *p. 
PM MAIL   Вверх
mes
Дата 19.12.2008, 00:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Не смешиваете команды употребляемые в одной строчке в одно нераздилимое целое. У каждого смыслового словосочетания свой результат и вместе они определяют каким будет "предложение" :
Код

char *  p; // указатель на участок памяти не зависиомо каким образом выделен.
// "словосочетания"
"name"; // выделение в сегменте данных памяти и помещение туда этой строки.  потерян, так как адрес не присвоен.
 new char[20]; // динамическое выделение массива. потерян так как не присвоен.
// "предложение:"
p = "name"; // выделение в сегменте данных памяти и помещение туда этой строки и присвоение этого адреса указателю p.
p = new char[20]; // динамическое выделение массива и присвоение этого адреса указателю p.


Добавлено через 2 минуты и 24 секунды
Цитата(yngwie19 @  19.12.2008,  00:08 Найти цитируемый пост)
mes, нет если просто объявлять *p.  

p это просто указатель. Он будет указывать на ту память на какую Вы ему скажете.


--------------------
PM MAIL WWW   Вверх
UnrealMan
Дата 19.12.2008, 03:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(mes @  18.12.2008,  23:41 Найти цитируемый пост)
потому что любое выражение в кавычках, вида "any" именуемое строкой, компилятор снабжает завершающим нулем и помешает в секцию данных,
а вместо него подставляет указатель типа (const) char * с адресом на этот участок памяти. 

Цитата(bsa @  18.12.2008,  23:44 Найти цитируемый пост)
"name" - это строковый литерал. В твоем случае он представляется в виде константы типа const char *.

Тип строкового литерала - всегда не char * и не const char *.
PM MAIL   Вверх
yngwie19
Дата 19.12.2008, 09:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 15.6.2008
Где: Новгород

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



Последний вопрос, допустим Я сделаю так
Код

char* ptr;
ptr = "name";

у меня данная строка запишется в сегмент памяти и возвратится указатель, а если у меня например по адресу ptr[1] или ptr[2] были данные, которые использует программа, а Я их таким образом сотру, как быть тогда?
Или при выделении памяти для "name" выбирается не используемый участок в памяти?
PM MAIL   Вверх
Сеппуку
Дата 19.12.2008, 10:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(yngwie19 @ 18.12.2008,  23:47)
mes, а почему тогда во втором случае ошибка, ведь ptr[10] это же есть указатель на первый элемент, т.е ptr.

char* ptr = "Some Text";  // В данном случае мы имеем указатель типа char

char array[10];  // А в этом случае константный указатель типа char. Сщщемуеымуттщ присвоить ему что то можно только во время объявления переменной, но никак не позже.


Короче говоря 

char array[10];

семантически эквивалентно 

char* const array = new char[10];

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

PM MAIL   Вверх
UnrealMan
Дата 19.12.2008, 10:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Сеппуку @  19.12.2008,  10:02 Найти цитируемый пост)
Короче говоря 

char array[10];

семантически эквивалентно 

char* const array = new char[10];

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

Вот даже как smile
Значит, если объявить массив в namespace scope, то он будет в стеке? Или если сделать его членом класса, а объект класса создать в динамической памяти - всё равно будет в стеке? А тут

Код
#include <iostream>

typedef char (&first)[1];
typedef char (&second)[2];

first f(char (&)[10]);
second f(void *);

int main()
{
    char array[10];
    char *pointer = new char[10];
    std::cout << (sizeof array == sizeof pointer) << std::endl;       // должно вывести 1?
    std::cout << (sizeof f(array) == sizeof f(pointer)) << std::endl; // должно вывести 1?
}

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

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

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

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

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


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

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


 




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


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

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