Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Программирование под Unix/Linux > Разница между масивом и вектором


Автор: admsasha 18.1.2007, 14:20
Объясните пожалуйста, все разница между
char a[10];
и
char* a;


В чем их отличия и чем приимущества... перечитал несколько статей, но так и не понял чем же пользоваться в какой ситуации...


Очень прошу вас помочь, так как совсем запутался...  smile   smile 

Автор: powerfox 18.1.2007, 14:27
admsasha, разница во всём.

Цитата(admsasha @  18.1.2007,  15:20 Найти цитируемый пост)
char a[10];

Массив с 10-ю элементами типа char.

Цитата(admsasha @  18.1.2007,  15:20 Найти цитируемый пост)
char* a;

Указатель на char.

Вот пример:
Код

char a[10];
char *pointer = a; //pointer указывает на a[0];
cout<<*(pointer++); //сначала pointer становится указателем на а[1], а потом выводится a[0]
some_func(pointer); //функции передаётся указатель, а не весь массив, что намного быстрее во многих случаях и экономит память.


Добавлено @ 14:32 
А вообще, это есть в любой книге по С/С++, причём в самом начале.

Добавлено @ 14:33 
admsasha, у меня в свою очередь 2 вопроса: 
при чём здесь вектор?
при чём здесь C/C++: Программирование под Unix/Linux?

Автор: admsasha 18.1.2007, 14:42
Цитата(powerfox @  18.1.2007,  21:27 Найти цитируемый пост)

А вообще, это есть в любой книге по С/С++, причём в самом начале.

Да, есть.... но чего то я не понял нечего... точнее запутался...  smile 


Цитата(powerfox @  18.1.2007,  21:27 Найти цитируемый пост)
при чём здесь вектор?
 Опечатался, вот только что хотел поменять название... но раз ответили уже... 


Цитата(powerfox @  18.1.2007,  21:27 Найти цитируемый пост)
при чём здесь C/C++: Программирование под Unix/Linux? 
  На всякий случай...

Автор: bilbobagginz 18.1.2007, 14:44
Код

char a1[10];
//в результате предыдущего выражения, появится переменная a, и аллоцируется кусок из 10 единиц типа char с неизвестным "наполнителем"
char* a2;
// в результате этого выражения появится переменная типа "указатель на char", неинициализированная.
// в C - это один и тот же тип данных, поэтому можно после написать:
a2=a1;



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


в первом случае всегда a1 указывает на валидный регион памяти, с неизвестными значениями.
во втором a2 может держать значение невалидного адреса, и при обращении по этому адресу произойдёт ошибка доступа к памяти
  •  на юникс - программа может получить сигнал SIGSEGV ( segment violation )
  •  на виндовс - выскочит ошибка "Access Valiolation" или что-то с Invalid memory
для избежания использования такого указателя надо его инициализировать хотя бы на NULL, и позже проверять на это.



пока.




Автор: admsasha 18.1.2007, 14:54
bilbobagginz, если я получаю строку из какого то ввода, из файла и т.д. т.е. точную длину незнаю, то в этом случае лучше всего использовать "указатель на char" ?

Автор: powerfox 18.1.2007, 15:15
admsasha, кничи тебе в помощь.


Цитата(admsasha @  18.1.2007,  15:54 Найти цитируемый пост)
bilbobagginz, если я получаю строку из какого то ввода, из файла и т.д. т.е. точную длину незнаю, то в этом случае лучше всего использовать "указатель на char" ?

Строки в Си ограничены нулём. Поэтому ты спокойно можешь найти её конец.

a) Ты читаешь с ввода посимвольно: читай пока не встретишь конец строки.

б) Получаешь сразу строку с помощью библиотечно функции. Вызови strlen и получишь длину строки.

Автор: admsasha 18.1.2007, 15:18
powerfox, Вопрос заключался не как это сделать,а в правильности выбора...

Автор: powerfox 18.1.2007, 15:31
Цитата(admsasha @  18.1.2007,  16:18 Найти цитируемый пост)
powerfox, Вопрос заключался не как это сделать,а в правильности выбора...

 smile 
Выбор зависит от того, как ты получаешь строку ))

Автор: admsasha 18.1.2007, 15:36
Цитата(powerfox @  18.1.2007,  22:31 Найти цитируемый пост)
Выбор зависит от того, как ты получаешь строку )) 


код может быть не совсем грамотный... 
Код

    fp = fopen(Config_FILE, "r");
    while(fgets(line, 1024, fp) !=NULL){
      // тут что-то должно быть
    }
    fclose(fp);


например так ?

Автор: powerfox 18.1.2007, 16:09
admsasha, да.

Автор: admsasha 18.1.2007, 16:19
powerfox,  char* line ?

Автор: powerfox 18.1.2007, 16:25
Учитывая объявление функции, то да. Но и char line[N] тоже должно работать, так как при вызове функции будет неявное преобразование в char*.

Автор: admsasha 18.1.2007, 16:37
Еще есть какое то
std::string s = "something";

это что ?

Добавлено @ 16:40 
Сравнение,вырезка, определение длины, это уже будут другие функции ? strcmp,strlen и.д. уже не подходят...   smile 

Автор: powerfox 18.1.2007, 16:42
Цитата(admsasha @  18.1.2007,  17:37 Найти цитируемый пост)
Еще есть какое тоstd::string s = "something";

Книгу по С++ тебе в руки.

Автор: MAKCim 18.1.2007, 16:51
Цитата

powerfox,  char* line ? 

нет, если ты память не динамически выделяешь (посредством malloc/calloc,...)

Автор: bilbobagginz 19.1.2007, 15:44
Цитата

Строки в Си ограничены нулём. Поэтому ты спокойно можешь найти её конец.

не факт. на это полагаться никак нельзя. Нужно считывать кусочками, ессно величина кусочка (а др. словами кол-во вызовов read(), fgets() и т.п. ) зависит от задачи. 

а насчёт std::string
саша, пойми: только в Си char* примерно то же, что и char [] с т.з. реализации и занимаемого пространства (места). в Си++ там всё по-другому.




Автор: MAKCim 19.1.2007, 17:24
Цитата

в Си++ там всё по-другому.

 smile  smile 

Автор: kirjanov 19.1.2007, 18:41
вроде в C++ строка является объктом

Автор: bilbobagginz 19.1.2007, 20:22
MAKCim, 
я советую почитать Б.Страуструпа.
в Си++ классах есть много добавок ( относительно struct в Си ), напр vfptr, vbptr и т.д. и т.п.
посмотри раздел: Technicalities, Section B ( compatibility )

пока.

Автор: MAKCim 19.1.2007, 20:36
Цитата

MAKCim, 
я советую почитать Б.Страуструпа.

 smile 
Цитата(bilbobagginz @  19.1.2007,  15:44 Найти цитируемый пост)
только в Си char* примерно то же, что и char [] с т.з. реализации и занимаемого пространства (места). в Си++ там всё по-другому.

см. выделенное
char* и char[] в С++ по-другому реализуются?
уточнять надо, что речь о классах идет...

Добавлено @ 20:39 
Цитата

вроде в C++ строка является объктом 

опять уточнять надо, что имеется в виду: строка литералов ("bla-bla-bla") или объект класса строки (std :: string)

Автор: admsasha 21.1.2007, 10:42
Вот допустим я создаю

char* a;

как сделать 
strcat(a,"123");
strcat(a,"345");

и как применить форматированый вывод ?

?

Автор: bilbobagginz 21.1.2007, 12:17
Код

char* a;

как сделать 
Код

strcat(a,"123");
strcat(a,"345");

и как применить форматированый вывод ?

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

strcat(a,"123");

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

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

char *a=malloc(10*sizeof(char));
/** проверяешь, что malloc() удался: */
if (NULL==a) {
/** ошибка */
}
/** нормальный ход программы, напр.: */
strcat(a,"123"); 


или же ты указываешь своим указателем на какой-то другой, валидный и правильный регион:
Код

char str[10]; /** система аллоцирует этот кусок для массива */
char *a=(str+2);  /** указываем на 3-й элемент в массиве ("строке") str */
/** теперь тоже можно сделать: */
strcat(a,"123");

и если обозначим неизвестно что значком "*", то в str будет:
Код

{ *,*,*,*,*,*'1','2','3',0};


загвоздка в том, что если ты в программе делаешь malloc(), то где-то надо освобождать это место при помощи free().

можно не освобождать, когда аллокация делается точное ограниченное число раз, тогда выходить надо с помощью exit(0);

судя по вопросам, тебе надо сначала прочитать книжку Б.Кернигана и Д.Ричи.



пока

Автор: admsasha 21.1.2007, 12:42
bilbobagginz, после твоего ответа теперь понял, что я вообще неправильно понимал, на счет char*, я пологал что это значит что могу пихать туда неограничено объема, а char[10] только 10знаков.


Автор: bilbobagginz 21.1.2007, 20:41
Цитата

bilbobagginz, после твоего ответа теперь понял, что я вообще неправильно понимал, на счет char*, я пологал что это значит что могу пихать туда неограничено объема, а char[10] только 10знаков.


это уже смотря куда ты им будешь указывать.

Есть ещё один пример с использованием указателей - в общих вопросах была тема с удалением лишних пробелов, http://forum.vingrad.ru/topic-132994/15.html#entry1005475

всё-таки книга "Язык программирования Си" от авторов  Брайан Керниган, Денис Ричи, т.н. "Библия Си" - хорошая и полезная книга: полный справочник и есть примеры, показывающие всё что стоит. И вообще пройдёт 5 лет после твоего последнего проекта на Си, перейдёшь ты на Си++ или другой язык - очень полезно, чтобы материал был под рукой.

То же относится и к "Язык программирования Си++" от Бьярна Страуструпа ( бери самое последнее издание)

а также в последствии ( если на Си++ перейдёшь ), то приобрети "Шаблоны Планирования" ( Design Patterns )
пока.

Автор: powerfox 21.1.2007, 21:56
Цитата(bilbobagginz @  21.1.2007,  21:41 Найти цитируемый пост)
Есть ещё один пример с использованием указателей - в общих вопросах была тема с удалением лишних пробелов, где Dov показал человеку элементарную арифметику указателей.

bilbobagginz, единственно, если бы 1 строка создавалась и удалялась через new и delete smile) Совсем уж законченный был бы пример.

Автор: admsasha 22.1.2007, 03:35
Цитата(bilbobagginz @  22.1.2007,  03:41 Найти цитируемый пост)
а также в последствии ( если на Си++ перейдёшь ), 

Я про C++ и спрашивал  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)