Использование разыменования в C++
Недавно начал читать книгу Джеффа Кента "C++ : Основы программирования". Сложностей, как мне кажется, нет никаких, однако когда я дошел до главы указателей, я понял, что все-таки есть что-то сложное... В конце концов с указателями я разобрался, но встал вопрос о разыменовании при использовании указателей в параметрах при передачи из функции, а так же при использовании их при динамическом распределении памяти.
1) Пример использования указателя без разыменования : Код:
#include <iostream> Код:
cin << x; Вообщем я запутался в том, что написал ;/ |
Код:
cout << str; // Почему работает без разыменования? Код:
cin.getline(name,80); Код:
cin << x; Вообще: Код:
const char* str = "my string"; // Тип — строка |
Перепутал операторы потокового ввода и вывода, извиняюсь.
Не понимаю значение слова "кастуется" :( Но если я правильно понял, то первое ваше замечание насчет std::cout было о том, что строка будет выводить без разыменования? Если да, то тогда для каких вообще переменных нужно разыменование при выводе? Я уверен на 100% только в том, что разыменование нужно для одиночной переменной. |
Каст (cast) — преобразование типа, в С++ const_cast, reinterpret_cast, static_cast, dynamic_type.
Разыменование — процесс получения данных под указателем. Код:
const char* str = "string"; Код:
const char* str1 = "1111"; |
Цитата:
Конечно в программе типа: Код:
int a = 1; |
Цитата:
Например вот небольшой mindfuck в С++: http://codepad.org/jO9y9T5j И таких mindfuck'ов в С++... |
Пришли да напугали...
Deamon, пояснение к коду? У меня все отрабатывает корректно. |
Цитата:
|
Цитата:
Таким же образом можно выстрелить себе в ногу в, скажем, строго-типизированном C#: Код:
public class MainClass |
Можно, но, судя по коду, намного сложнее :)
|
Цитата:
|
Цитата:
|
Раз уж отошли от темы, тогда поясните, пожалуйста, что значит оператор " -> "?
|
Для выбора объекта.
|
Цитата:
Код:
class A |
Цитата:
|
Цитата:
|
Дочитал книжку, однако там так и не были описаны операторы для работы с символьными строками и символьными массивами. Нашел в интернете, что следующая функция-член работает и с С-строками и классой С++ строк : str.erase(i,k) - где i - № символа, с которого удалется k-символов. Так ли это?
Так же я не нашел оператора, функции-члена или библиотеки для поиска нужных символов в строке. Допустим, дана строка : str="lol what.wtf.12" Мне из неё нужно получить число 12. Конечно, можно проверять каждый символ isdigit'том, но если мне известно, что в строке есть число, которое хранится в переменной X, не проще ли будет найти первое вхождение строки X в строку STR?.. В Turbo Pascal'е есть такая хорошая команда : pos(str,x). Однако гугл трубит в рог с заявлением, что такой команды нет :( Так есть или нет? А если нет, то мне придется перебирать все символы до тех пор, пока не наткнусь на тот же, с которого начинается строка X, затем пройтись с помощью x.length() по строке STR, копировать все символы оттуда по длине X и записать их в STR2, а затем сравнить эти две строки? D: p.s Или может у вас есть ссылка, где описаны операторы и функции-члены для работы с классой С++ строк и С-строк? p.p.s Можно ли задать динамический массив, а затем его использовать таким образом : int x; int*massiv=new int[x]; x=2; // а затем, если мне понадобится более 2ух элементов сделать следующее x++; // станет ли массив из трех элементов, если я переназначу переменную по ходу дела и что будет с массивом из трех элементов с УЖЕ ПРИСОВЕННЫМИ ЗНАЧЕНИЯМИ если сделать следующее x--; p.p.p.s И да, если я вдруг задал ну о-о-о-очень тупой вопрос, пожалуйста, не высылайте за мной 03 :( |
Цитата:
собственно функция для поиска подстроки внутри строки называется strstr() Раздел MSDN описывающий работу со строками http://msdn.microsoft.com/ru-ru/library/f0151s4x.aspx или тут http://www.cplusplus.com/reference/c...string/strstr/ Так же можно использовать класс std::string из STL Ну и в любом фреймворке есть свои реализации класса строки, например CString в ATL\MFC. Цитата:
В твоем примере переменная x и massiv никак не связаны, и изменение x ни коим образом не влияет на massiv. Более того это ошибка - использование переменной без инициализации. если нужен массив из двух int то пишем Код:
int *array = new int[2]; Код:
int *tmp = new int[3]; // выделяем память под новый массив из 3 элементов Правда если array содержит данные не простого типа, а некоего класса, то memcpy конечно же использовать нельзя. Прийдется в цикле сделать присваивание поэлементное: Код:
for (int i = 0; i < 2; i++) В чистом с++ нет понятия динамический массив, для этого используй класс из STL std::vector |
Цитата:
int elems=1,amount,mDel=0; int*massiv=new int[elems]; // В книге так динам. массив задавался. ...code... cin >> amount; // Кол-во, допустим, человек. for (int i=0;i<amount; i++) if (massiv[i]<max) mDel+=1; // Вышли из цикла. if (mDel==amount) {...code...} // В коде идет проверка такого плана : если у всех элементов значение меньше переменной MAX, то в массиве остается лишь одна строчка, а все остальные удаляются при помощи либо обнуления через for, либо просто изменения значения elems на 1, чтобы массив имел один элемент, а все остальные (не знаю, удалятся ли они по условию...) удалились. Проще, наверное, будет привести полный пример. Вот моя ломаная ( :< ) программа, где я хотел использовать то, о чем писал. Однако при первом вводе ученика, она выдает ошибку дебагера. Задание : в первой строке вводится N-кол-во учеников. В каждой из последующих N-строк идет информация о каждом в виде First-name Second-name School Grade. Нужно вывести номер школы, в которой больше всего учеников, набравших наивысший балл на районе. Т.е, если входные данные такие : DAWd dawd 3 87 jdiaw jkdw 3 87 dwaji hjw 2 87 выходные данные будут такие : 3 p.s Не вышло объявить двумерный динамический массив : ( Код:
#include <iostream> |
Цитата:
А вот исходник я не осилил. Если я правильно понял задачу, то вот мой вариант решения: Код:
#include <iostream> |
Цитата:
Однако... проблема в том, что кол-во учеников может быть, как написано в задаче, до 100.000. Что дает ОГО-ГО-ГО мусорной памяти при динамическом массиве на 100.000 учеников, так ещё и для структуры в 3 переменных экземпляра. А использовать из них нужно только тех, у кого наивысшие баллы, то есть, если нашелся человек с наивысшим баллом, можно сразу весь массив потереть. Именно поэтому мне нужно по ходу дела менять массив. p.s Кстати, а почему практически никто не использует using namespace std; ? p.p.s Только доперло насчет того куска кода, где ты показывал легкую альтернативу std::vector. Даже если каждый раз пересоздавать массив, то я, в конце концов, столкнусь либо с уймой проверок, так как пересоздание массива должно быть ПРЯМО в цикле for, а это значит, что на разные итерации нужны разные объявления массивов. Тут уж я чекнусь быстрее, но за то, что показал такой подход, спасибо! ^^ p.p.p.s Кстати, в этой задачи имена не нужны вообще, а потому я просто использовал строковую str и больше её не использовал (Вот в чем ошибка >_< я её в int занес, а вводил имя >_____<! Теперь все работает, и, похоже, прямо во время работы программы размер массива меняется в зависимости от pol++ или pol=1. Однако, у меня там ошибка в конце, из-за чего всегда должно быть две и более школ, в которых есть хотя бы по одному ученику с наивысшим баллом, иначе ошибка). Можно ли как-то, как динамический массив, во время работы программы выпилить одну переменную или не динамический массив из памяти процесса? p.p.p.p.s Кстати, мне компилятор на твое решение матерится Оо 1>d:\git\tests\helloworld!\example.cpp(10) : error C2061: syntax error : identifier '_TCHAR' |
Цитата:
Цитата:
Многомерные массивы динамически нормально не создаются, требуются разного рода ухищрения. Самый нормальный вариант использовать какой-нибудь готовый класс, ну или написать самому. Цитата:
Согласен можно исключить из структуры name, оно все равно не используется. А остальное, даже при количестве данных в 100000, объем занимаемой памяти будет равен 12 * 100000, то есть чуть больше 1 мегабайта, что является сущим пустяком. Цитата:
Цитата:
Кстати сейчас вот сел еще раз почитал условие задачи, мой алгоритм неверный. На работе в попыхах не совсем верно понял. |
Вот 100% рабочий вариант -)
Первая часть где ввод данных и вычисление максимального бала - не изменилась. И кстати занимать памяти это дело будет всего 782 Кбайта при количестве элементов 100000. И я никак не пойму твою идею насчет выкидывания каких-то данных в процессе ввода. Данные можно проанализировать после того как они все введены, иначе будет неполный анализ. И совет небольшой - не занимайся пока никакой оптимизацией. Сперва просто напиши любой код, каким бы ужасным он не был, который просто справляется с поставленной задачей - это главное. Потом с опытом прийдут в голову более оптимальные решения. Код:
#include <tchar.h> |
Все, врубился! Идея в том что после ввода максимальной оценки все предыдущие данные становятся неактуальными. Вот измененный вариант без выделения памяти вообще, все считается в процессе ввода. Единственное что не учтено - то что если две или более школы наберут одинаковое количество максимальных балов. Победителем будет та школа которая первой ввелась -)
Код:
#include <tchar.h> |
Получается, если я включу директиву tchar.h, а затем помечу main, как _tmain с необходимыми параметрами, то на ввод и вывод я смогу использовать любой язык, пусть даже русский или японский?
Убил мозг конструкцией std::map<int,int> schoolmap;. В книге об этом написано не было ;/ В итоге нашел такое : map <key_type, value_type [, comparing_option [, memory_allocator] ] > map_name - и прочее на http://en.wikipedia.org/wiki/Map_(C%2B%2B) . Но я от природы глупый и ничего в этом не понял : ( Есть где попроще написано? Желательно с простыми примерами, ато на вики самый просто пример уже вбил в ступор из-за std::cin >> s && , я даже до map не дошел :/ p.s Насчет того, чтобы не заморачиваться с оптимизацией. Дело в том, что я уже решал эти задачи на Pascal'е. Это был мой первый язык. Вот там таки было ещё хуже, ведь массив нельзя объявить ничем, кроме литерала или константы. Там пришлось ухищряться, а тут гораздо проще выходит, поэтому я и решил продвинуться вперед и попробовать сделать более или менее оптимизированный динамический массив. (именно поэтому я так судорожно бился за каждую лишнюю строчку, так как это задача из с4, а там на оптимизацию смотрели). |
Цитата:
Просто такие обертки создает сама студия при генерации нового проекта. Если UNICODE определен, то _tmain разворачивается в уникодный вариант, TCHAR в wchar_t, иначе просто в char. Цитата:
Цитата:
|
Как можно 1 символ перегнать в тип int? atoi и прочие считывают только строки : (
|
Цитата:
Код:
char c = '9'; |
Получается, что можно любой целочисленной переменной присвоить значение символа, просто в ц.переменной будет его ASCII код? А если я хочу обратно переделать? Т.е из, допустим, кода 132 ASCII, который хранится в переменной i=132, получить её символ, что мне нужно сделать? В Pascal'е был унарный оператор #...
|
(char)i
|
Что ж такое, опять проблемы с одинарными символами ;/ На этот раз мне нужно следующее. Есть строка, в ней мне нужны определенные 10 символов, работу с ними я уже организовал - спасибо вам за подсказку ^^ - а вот проверка не выходит. Дело в том, что каждая строка имеет тип string, и если первые 8 символов Dialogue, то выполняется функция, иначе итерация заканчивается. Я пытался и так :
string lolz=textLine[0]+textLine[1]....textLine[7]; и так : char dialogue[8]; for (int i=0;i<8;i++) strcat(dialogue,textLine[i]); Как только не пытался. Все в пустую ;\ Подскажите, как вообще не сломать себе мозг с этими одинарными символами и что сделать мне в приведенной выше программе, чтобы проверка работала нормально? |
if(0 == strncmp(str.c_str(), "Dialogue", 8))
|
Цитата:
Предположим, что пользователь вводить строку, которая является именем файла. cin >> x; Где x=*****.mkv или x=*****.cpp, и мне нужно узнать, что же он ввел за расширение и, исходя из этого, редактировать файл. |
Цитата:
ну а по существу вопроса - лучше пользоваться не приехавшими из C функциями а STL шаблонами. в данном случае string::compare, там можно задавать позиции сравнения. |
http://www.cplusplus.com/reference/s.../find_last_of/
тут пример есть |
Цитата:
|
да ладно вам...большая часть юзеров виндовс вообще ничего не знает о расширениях ( в win XP оно по умолчанию скрыто для зарегистрированных файлов).
|
Цитата:
И я если вижу расширение .mkv - то я считаю что кино полагаясь только на расширение, а не лезу в хекс редактор сверить заголовок файла на предмет соответствия его формату mkv. |
Текущее время: 21:22. Часовой пояс GMT +3. |
ru-mangos.ru - Русское сообщество MaNGOS