Разбор примеров из книги
Модераторы: Oleg_D, Модераторы
Спасибо! Полностью понял теперь! Очень помогли!
deka47 писал(а):Спасибо! Полностью понял теперь! Очень помогли!
Когда до меня туго доходят какие-то вещи, то иногда откладываю проблему на несколько дней, пока в голове немного "утрамбуется". И позже задача решается.
Добавлено спустя 2 часа 3 минуты 36 секунд:
Да, и ещё маленькое пояснение к этой же программке. Выражение
if not flag then ...
равносильно
if flag=false then ...
Подойдя к финалу нашего проекта, мы научились: 1) шифровать отдельную строку, 2) читать строки из файла и 3) записывать строки в файл. Пора соединить все это: читая строки исходного файла, будем шифровать их, и записывать в другой файл, – так будет работать наша программа. В комментариях я обьясню как Я вижу программу. Она у меня шифрует в Crypt что-то, когда открываю Crypt.txt, то там вижу набор непонятных символов, но потом с Crypt она не дешифрует в Decrypt, тот текст, который был в Text.txt. Что не верно?
Код: Выделить всё
var CKey: integer; {ключ}
function Crypt(arg: char): char;
var x: integer;
begin
x:=Ord(arg)+CKey;
if x>255 then x:= x-256+32;
Crypt:= Char(x);
end; {шифрование символа}
function DeCrypt(arg: char): char;
var x: integer;
begin
x:=Ord(arg)-CKey;
if x<32 then x:= x+256-32;
DeCrypt:= Char(x);
end; {дешифрование символа}
procedure CryptString(var s: string); {считывания строки s в процедуру}
var k: integer;
arg: string;
begin
for k:=1 to Length(s) do
s[k]:=Crypt(arg[k]);
end; {шифрование всех символов строки s}
procedure DeCryptString(var s: string); {считывание зашифрованной строки s в процедуру}
var k: integer;
arg: string;
begin
for k:=1 to Length(s) do
s[k]:= DeCrypt(s[k]);
end; {дешифрование всех зашифрованных символом процедурой CryptString}
var f, q, m: text; {3 текстовых файла}
Oper: integer;
s: string;
begin
write ('Key - '); readln (Ckey); {пишем ключ}
Writeln ('Укажите операцию: 1 – шифровать, 2 – дешифровать, прочие - выход'); Readln(Oper);
case Oper of
1: begin {если 1, то шифруем тхт документ в другой тхт документ}
assign (f, 'C:\Users\Text.txt');
reset (f); {открытие обычного тхт документа, с обычным читабетельным текстом}
assign (q, 'C:\Users\Crypt.txt');
rewrite (q); {открытие пустого тхт документа для записи зашифрованного текста}
while not eof(f) do begin readln (f, s); CryptString(s); writeln (q, s); end; {пока не найден конец строки в тхт документе f мы читаем строку из
файла f и заносим ее в стринговую s, потом шифруем строку s, потом записываем в пустой файл q эти зашифрованные строки}
close (f); {закрываем}
close (q); {закрываем}
end;
2: begin {если 2, то дешифруем тхт документ в другой тхт документ}
assign (q, 'C:\Users\Crypt.txt');
reset (q); {открытие тхт документа с зашифрованным текстом, который я, как бы, сделал выше}
assign (m, 'C:\Users\DeCrypt.txt');
rewrite (m); {открытие пустого тхт документа для записи рассшифрованного текста}
while not eof(q) do begin readln (q, s); DeCryptString(s); writeln (m, s); end; {пока не найден конец строки в тхт документе q мы читаем строку из
файла q и заносим ее в стринговую s, потом рассшифруем строку s, потом записываем в пустой файл m эти рассшифрованные строки}
close (q); {закрываем}
close (m); {закрываем}
end;
end;
end.- Paster Fob
- постоялец
- Сообщения: 188
- Зарегистрирован: 22.02.2011 20:53:36
- Откуда: Новосибирск.
deka47 писал(а):Она у меня шифрует в Crypt что-то, когда открываю Crypt.txt, то там вижу набор непонятных символов, но потом с Crypt она не дешифрует в Decrypt, тот текст, который был в Text.txt. Что не верно?
deka47 В процедуру CryptString передаётся строка из исходного файла,затем в функцию Crypt должен передаться один из символов строки,а возвратиться уже зашифрованный.
А у вас что?Передаётся в функцию неизвестно что.Отсюда такой результат.Всё то же и для процедуры DeCryptString.
Код: Выделить всё
procedure CryptString(var arg:string);
var k: integer;
begin
for k:=1 to Length(arg) do
arg[k]:=Crypt(arg[k]);
end;
procedure DeCryptString(var arg:string);
var k:integer;
begin
for k:=1 to Length(arg) do
arg[k]:=DeCrypt(arg[k]);
end;И пишите код "лесенкой" потом самому легче разобраться.
В целом понял, но в поправленном коде вы всего лишь изменили s на arg? У меня s тоже была string, какая разница какая буква или выражение? Я имею ввиду s или arg? Какую роль это здесь сыграло? У меня было все точь в точь, но просто введена другая переменная.
Добавлено спустя 2 минуты 14 секунд:
Все дошло, если я ввел в процедуре переменную s, то мне стоило было сделать это и в функции для нормального фунциклирования программы. Спасибо!
Добавлено спустя 2 минуты 14 секунд:
Все дошло, если я ввел в процедуре переменную s, то мне стоило было сделать это и в функции для нормального фунциклирования программы. Спасибо!
- Paster Fob
- постоялец
- Сообщения: 188
- Зарегистрирован: 22.02.2011 20:53:36
- Откуда: Новосибирск.
deka47 писал(а):Все дошло, если я ввел в процедуре переменную s, то мне стоило было сделать это и в функции для нормального фунциклирования программы. Спасибо!
Я то же учусь по этой книге,когда дело дошло до процедур и функций стал испытывать трудности,затем разобрался и теперь практически во всех программах использую их.Здесь на форуме в отдельной теме я спрашивал о подпрограммах мне объясняли.
Что каксается вашего кода,для чего вообще вы объявили переменную arg в процедурах и даже не присвоили ей никакого значения?
Переменная arg не инициализирована,что в ней находиться не известно.
Если формальный параметр объявлен через var или const,то по сути это и есть переменная на которую он ссылается.Если параметр объявлен без ссылки на переменную,то это уже другая переменная,но с тем же значением на которую ссылается.Т.е. используемый в теле процедуры параметр s это и есть переменная s главной программы(фактический параметр).
Вы же объявляете локальную переменную arg в теле процедуры и передаёте её в функцию,но ведь её значение не определенно.В таком случае процедура должна выглядеть так:
Код: Выделить всё
procedure CryptString(var s:string);
var k: integer;arg:string;
begin
arg:=s;
for k:=1 to Length(arg) do
arg[k]:=Crypt(arg[k]);
end;В любом случае локальной переменной arg не должно быть.
Но даже если и ввел, то:
Она у меня здесь никакого значения не набывает и нигде не используется, пусть будет, она же никак не влияет на программу?
Этот arg не процедурный, а от функции, верно?
Я просто ввел переменную и ничего с ней не делал, как она влияет на программу?
А мое утверждение на счет того, что переменная в обьявленная в функции должна совпадать с переменной обьявленной в процедуре не верно?
Код: Выделить всё
procedure CryptString(var s: string); {считывания строки s в процедуру}
var k: integer;
arg: string;
begin
for k:=1 to Length(s) do
s[k]:=Crypt(arg[k]);
end; {шифрование всех символов строки s}Она у меня здесь никакого значения не набывает и нигде не используется, пусть будет, она же никак не влияет на программу?
Код: Выделить всё
s[k]:=Crypt(arg[k]);Этот arg не процедурный, а от функции, верно?
Я просто ввел переменную и ничего с ней не делал, как она влияет на программу?
А мое утверждение на счет того, что переменная в обьявленная в функции должна совпадать с переменной обьявленной в процедуре не верно?
- Paster Fob
- постоялец
- Сообщения: 188
- Зарегистрирован: 22.02.2011 20:53:36
- Откуда: Новосибирск.
deka47 писал(а):Она у меня здесь никакого значения не набывает и нигде не используется, пусть будет, она же никак не влияет на программу?
Она используется в функции и если бы не влияла,то программа работала бы правильно.
Код: Выделить всё
s[k]:=Crypt(arg[k]);deka47 писал(а):Этот arg не процедурный, а от функции, верно?
Я просто ввел переменную и ничего с ней не делал, как она влияет на программу?
этот arg не от функции,это локальная переменная объявленная не понятно зачем в процедуре.
Код: Выделить всё
procedure CryptString(var s: string);Код: Выделить всё
var k: integer;Код: Выделить всё
arg: string ;Код: Выделить всё
for k:=1 to Length(s) doКод: Выделить всё
s[k]:=Crypt(arg[k]);Код: Выделить всё
s[k]:=Crypt(s[k]);Так понятно?
deka47 писал(а):А мое утверждение на счет того, что переменная в обьявленная в функции должна совпадать с переменной обьявленной в процедуре не верно?
Да не верно.Вообще имена переменных в параметре как и обычных могут иметь любое имя кроме зарезервированных слов.
Последний раз редактировалось Paster Fob 22.10.2012 05:35:52, всего редактировалось 2 раза.
Paster Fob писал(а):Так понятно?
Да, я понял. Спасибо.
всем доброго времени суток!
прошу дать ответ на задачку (А) глава 24:
Измените программу шифрования так, чтобы ключ задавался
пользователем с клавиатуры и передавался в процедуры и функции через параметр.
Заголовки процедур и функций сделайте такими.
function CryptChar(arg: char; key: integer): char;
procedure CryptString(var arg: string; key: integer);
прошу дать ответ на задачку (А) глава 24:
Измените программу шифрования так, чтобы ключ задавался
пользователем с клавиатуры и передавался в процедуры и функции через параметр.
Заголовки процедур и функций сделайте такими.
function CryptChar(arg: char; key: integer): char;
procedure CryptString(var arg: string; key: integer);
Код: Выделить всё
const key=5; {наш ключ}
function charcrypt(arg:char):char; {функция шифрации символа}
var x:integer; {локальная переменная}
begin {тело функции}
x:=ord(arg)+key; {присваиваем x=код символа+ключ}
if x>255 then x:=x-256+32; {избавляемся от кодов управляющих символов}
charcrypt:=char(x); {присваиваем имени функции символ через код x}
end; {конец функции }
function chardec(arg:char):char;
var x:integer;
begin
x:=ord(arg)-key;
if x<32 then x:=x+256-32;
chardec:=char(x)
end;
procedure strcrypt(var arg:string); {процедура шифрации строки через функцию}
var x:integer;
begin
for x:=1 to length(arg) do
arg[x]:=charcrypt(arg[x]); {возвращаем сроку через символы функции }
end;
procedure strdec(var arg:string);
var x:integer;
begin
for x:=1 to length(arg) do
arg[x]:=chardec(arg[x]);
end;
{обьявления глобальных переменных}
var s:string;
x:integer;
begin {начало главной программы}
repeat
writeln('введите строку'); readln(s);
writeln('введите цифру 1 для шифровки 2 для дешифровки или другое для выхода');
readln(x);
case x of
1: strcrypt(s);
2: strdec(s);
else break; {прерываение цикла repeat}
end;
writeln(s);readln;
until false; {бесконечный цикл}
end.
- Paster Fob
- постоялец
- Сообщения: 188
- Зарегистрирован: 22.02.2011 20:53:36
- Откуда: Новосибирск.
В чём проблема-то?
Код: Выделить всё
function charcrypt(arg:char;key:integer):char; {функция шифрации символа}
var x:integer; {локальная переменная}
begin {тело функции}
x:=ord(arg)+key; {присваиваем x=код символа+ключ}
if x>255 then x:=x-256+32; {избавляемся от кодов управляющих символов}
charcrypt:=char(x); {присваиваем имени функции символ через код x}
end; {конец функции }
function chardec(arg:char;key:integer):char;
var x:integer;
begin
x:=ord(arg)-key;
if x<32 then x:=x+256-32;
chardec:=char(x)
end;
procedure strcrypt(var arg:string;key:integer); {процедура шифрации строки через функцию}
var x:integer;
begin
for x:=1 to length(arg) do
arg[x]:=charcrypt(arg[x],key); {возвращаем сроку через символы функции }
end;
procedure strdec(var arg:string;key:integer);
var x:integer;
begin
for x:=1 to length(arg) do
arg[x]:=chardec(arg[x],key);
end;
{обьявления глобальных переменных}
var s:string;
x,key:integer;
begin {начало главной программы}
repeat
writeln('введите строку'); readln(s);
writeln('введите цифру 1 для шифровки 2 для дешифровки или другое для выхода');
readln(x);
if (x=1) or (x=2) then begin
writeln('Введите ключ');
readln(key);
end;
case x of
1: strcrypt(s,key);
2: strdec(s,key);
else break; {прерываение цикла repeat}
end;
writeln(s);
until false; {бесконечный цикл}
end.[quote="Paster Fob"]В чём проблема-то?
моя проблема в том что я не понимаю для чего указывать в процедуре сылку на ключ+как срабатывает это выражение arg[x]:=charcrypt(arg[x],key);
моя логика вводит меня в заблуждение: процедура передает шифрацию каждого символа функции для каждого следующего символа строки и возвращает обратно в процедуру, тут я путаюсь зачем передавать переменную ключа в процедуру?
сидел минут 10 и только начал понимать, получается так что функция не видит ключа без помощи процедуры, так как именно процедура передает данные переменных в функцию. Верно?
моя проблема в том что я не понимаю для чего указывать в процедуре сылку на ключ+как срабатывает это выражение arg[x]:=charcrypt(arg[x],key);
моя логика вводит меня в заблуждение: процедура передает шифрацию каждого символа функции для каждого следующего символа строки и возвращает обратно в процедуру, тут я путаюсь зачем передавать переменную ключа в процедуру?
сидел минут 10 и только начал понимать, получается так что функция не видит ключа без помощи процедуры, так как именно процедура передает данные переменных в функцию. Верно?
Код: Выделить всё
function charcrypt(arg:char;key:integer):char; {функция шифрации символа}
var x:integer; {локальная переменная}
begin {тело функции}
x:=ord(arg)+key; {присваиваем x=код символа+ключ}
if x>255 then x:=x-256+32; {избавляемся от кодов управляющих символов}
charcrypt:=char(x); {присваиваем имени функции символ через код x}
end; {конец функции }
procedure strcrypt(var arg:string;key:integer); {процедура шифрации строки через функцию}
var x:integer;
begin
for x:=1 to length(arg) do
arg[x]:=charcrypt(arg[x],key); {возвращаем сроку через символы функции }
end;Scraper писал(а):сидел минут 10 и только начал понимать, получается так что функция не видит ключа без помощи процедуры, так как именно процедура передает данные переменных в функцию. Верно?
Именно так. В книжном примере использована глобальная константа, которая видна из всех процедур и функций. Поэтому передавать её через параметр не было нужды. Но в больших профессиональных программах делают так, как решено у Paster Fob. Как верно подметил Paster Fob, на данном этапе учащемуся важно научиться строить процедуры и функции и разобраться с передачей параметров, -- дальше без этого не обойтись. И ещё совет: форматируйте текст программы, как это обычно принято.
Paster Fob Oleg_D большое спасибо за разъяснения. У меня еще один вопрос к Вам: в 30 лет начинать учиться не поздно? Просто времени учиться не много 1-2 часа в сутки. Стараюсь форсировать, но тут важнее проникать в детали, частенько приходиться пробуксовывать. Вот ваше мнение как опытных программистов меня очень интересует.
Scraper писал(а):в 30 лет начинать учиться не поздно?
Учиться никогда не поздно. Тем более, при наличии желания, подходящих личных качеств и хорошего базового технического образования. Я уже говорил где-то, что "чистых" программистов требуется не так уж много, это тонкая прослойка элиты. Нужны инженеры, способные ставить себе задачи применительно к разным отраслям человеческой деятельности. Или понимающие постановку таких задач.
