Форум программистов, компьютерный форум CyberForum.ru

Возвращение функциями указателей - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 18, средняя оценка - 4.67
Rusl_v
 Аватар для Rusl_v
13 / 12 / 1
Регистрация: 22.12.2010
Сообщений: 67
24.01.2011, 00:21     Возвращение функциями указателей #1
Доброго времени суток
Помогите понять код!!!Суть вопроса описана в коментах в коде.
Условие задачи:В программе демонстрируеться использование указателя в качестве типа возвращаемого значения.Ф-ция get_substr() возвращает указатель на первую подстроку(найденную в строке),которая совпадает с заданной.Если заданная подстрока не найдена,возвращается нулевой указатель.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include "stdafx.h"
#include <iostream>
using namespace std;
 
char *get_substr(char *sub,char *str);
    
 
int _tmain(int argc, _TCHAR* argv[])
{
    setlocale(LC_ALL,"Russian");
    char *substr;
    substr=get_substr("три","один два три четыре");
    cout<<"Заданная подстрока найдена:"<<substr;
    cout<<"\n";
    system("pause");
    return 0;
}
char *get_substr(char *sub,char *str)
{
    int t;
    char *p,*p2,*start;
    for(t=0;str[t];t++){            
        p=&str[t];                  
        start=p;                    
        p2=sub; //указатель всегда указывает на начало строки,т.е. буквы 'т'!!!(в цикле while он индексируеться)        
        while(*p2&&*p2==*p){    //При обнаружении 'т'=='т',передаёться это значение из ф-ции,так же 'р'=='р','и'=='и'
            p++;        //После обнаружение пробела и букв "четыре" это условие не выполняеться,т.к. p2 не равно p
            p2++;   //следовательно p2 не индексируеться
        }
        if (!*p2)       //следовательно это условие не выполняеться,т.к.
            return start;   //p2=sub;(начало цикла)...Так почему ретурн передаёт указатель на буквы "четыре" дальше??? 
    }                   //Результат выполненой программы:
    return 0;               //Заданная подстрока найдена:три четыре
}                       //В чём прикол не пойму,поидее тогда ретурн должен возвращать все буквы и не искать ничего,если по этой логике...
Где я не допонял подскажите,ломаю голову с самого утра над этим кодом.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
24.01.2011, 01:20     Возвращение функциями указателей #2
Rusl_v, if (!*p2)
Каким-то странным мне кажется это условие. Ты уверен что ты добиваешься именно этого? Если по адресу p2 содержится ноль - тогда выходим из функции?
panicwassano
590 / 558 / 20
Регистрация: 07.11.2010
Сообщений: 2,004
24.01.2011, 01:38     Возвращение функциями указателей #3
код из книги Шилдта, причем там все подробно расписано
Forever там суть такая берем первый символ и от него начинаем искать подстроку, соответственно если совпадает то указатель *p2 указывает на 0, и тогда выходим из функции т.к. нашли подстроку. Если это не так берем второй символ и от него ищем и т.д
Rusl_v вложенный цикл while ищет подстроку начиная с символа str[0], соответственно если буквы равны и НЕ конец подстроки, то передвигаем указатель. Если указатель не будет указывать на 0, то берем символ str[1] и от него ищем подстроку
Rusl_v
 Аватар для Rusl_v
13 / 12 / 1
Регистрация: 22.12.2010
Сообщений: 67
24.01.2011, 02:27  [ТС]     Возвращение функциями указателей #4
Цитата Сообщение от ForEveR Посмотреть сообщение
Rusl_v, if (!*p2)
Каким-то странным мне кажется это условие. Ты уверен что ты добиваешься именно этого? Если по адресу p2 содержится ноль - тогда выходим из функции?
Привет).if (!*p2) - я так понимаю что это служит для определения конца строки и передачи букавок "три"(return start срабатывает).Но почему он дальше передаёт букавки вот это вопрос,цикл while же не выполняеться,следовательно p2 не итерируется.Вот как бы вопрос

Добавлено через 5 минут
Цитата Сообщение от panicwassano Посмотреть сообщение
код из книги Шилдта, причем там все подробно расписано
Forever там суть такая берем первый символ и от него начинаем искать подстроку, соответственно если совпадает то указатель *p2 указывает на 0, и тогда выходим из функции т.к. нашли подстроку. Если это не так берем второй символ и от него ищем и т.д
Rusl_v вложенный цикл while ищет подстроку начиная с символа str[0], соответственно если буквы равны и НЕ конец подстроки, то передвигаем указатель. Если указатель не будет указывать на 0, то берем символ str[1] и от него ищем подстроку
Мы не выходим из функции пока цикл не закончиться правильно for(t=0;str[t];t++)?
А почему тогда "четыре" тоже находит они же не равны со второй строкой???указатель start возвращает по символу правильно я понимаю???

Ребят я вас чуток подгружу тут вы не против??))Я просто ф-ции начал изучать вроде всё понял но тут явно какоето колдунство))

Добавлено через 33 минуты
Получаеться что *start передаёт не по одной букве а передаёт ВСЮ строку после буквы 'т'???Так что-ли получаеться?
Nameless One
Эксперт С++
 Аватар для Nameless One
5754 / 3403 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
24.01.2011, 05:40     Возвращение функциями указателей #5
Цитата Сообщение от Rusl_v Посмотреть сообщение
Получаеться что *start передаёт не по одной букве а передаёт ВСЮ строку после буквы 'т'???Так что-ли получаеться?
start - это указатель на строку (объявленный как char* start).
Поэтому, возвращая start, ты возвращаешь указатель на некоторую область памяти (в которой, предположительно, храниться массив символов - строка).
Вот тебе пример: вызов функции get_substr c аргументами sub = "ab" (подстрока, которую мы ищем) и str = "cabk" (строка, в которой мы ищем подстроку). При этом, и sub, и str сами являются указателями, т.е. хранят некоторый адрес, по которому хранится строка. Предположим, что str = offset, т.е. по адресу offset в памяти распологается символ 'c', по адресу offset + 1 -- символ 'a', offset + 2 -- символ 'b', по адресу offset + 3 -- символ 'k', по адресу offset + 4 -- символ '\0' (нуль-терминатор, символ, который в С играет роль конца строки):

http://www.cyberforum.ru/cgi-bin/latex.cgi?\begin{array}{|c||c|c|c|c|c|c|}address & offset + 0 & offset + 1 & offset + 2 & offset + 3 & offset + 4 & offset + 5\\<br />
\hline \\<br />
character & 'c' & 'a' & 'b' & 'k' & 0 & ... \\<br />
\end{array}

Первое вхождение подстроки начинается с символа 'a', поэтому мы возвращаем адрес offset + 1, а по этому адресу хранится строка "abk".

Не по теме:

Цитата Сообщение от panicwassano Посмотреть сообщение
код из книги Шилдта, причем там все подробно расписано
По хорошему, автору бы надо было объявлять формальные параметры и локальные указатели в функции get_substr со спецификатором const

Rusl_v
 Аватар для Rusl_v
13 / 12 / 1
Регистрация: 22.12.2010
Сообщений: 67
24.01.2011, 10:22  [ТС]     Возвращение функциями указателей #6
Даже так....хм,очень большое спасибо за разъяснения.Я всегда предполагал что каждый символ имеет свой адрес так сказать личный,а указатель ссылается на этот адрес каждого символа, из-за этого у меня появилось куча вопросов.
А тут получается:__________А я думал что:
offset+0 - 'c''a''b''k''0' _______offset+0 - 'c'
offset+1 - 'a''b''k''0' _________offset+1 - 'a'
offset+2 - 'b''k''0' ___________offset+2 - 'b'
offset+3 - 'k''0' _____________offset+3 - 'k'
offset+4 - '0' ______________offset+4 - '0'


Всем спасибо
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
24.01.2011, 10:29     Возвращение функциями указателей #7
Цитата Сообщение от Rusl_v Посмотреть сообщение
Даже так....хм,очень большое спасибо за разъяснения.Я всегда предполагал что каждый символ имеет свой адрес так сказать личный,а указатель ссылается на этот адрес каждого символа
В принципе так и есть. Но среди этих символов есть тот, с которого строка начинается, указатель на который как раз и берётся за указатель на всю строку. Но если надо, то можно для каких нибудь целей вычислить указатель на любой символ, сложив его номер с указателем на саму строку, причём, нумеровать символы придётся с нуля.
Rusl_v
 Аватар для Rusl_v
13 / 12 / 1
Регистрация: 22.12.2010
Сообщений: 67
24.01.2011, 11:21  [ТС]     Возвращение функциями указателей #8
Цитата Сообщение от taras atavin Посмотреть сообщение
В принципе так и есть. Но среди этих символов есть тот, с которого строка начинается, указатель на который как раз и берётся за указатель на всю строку. Но если надо, то можно для каких нибудь целей вычислить указатель на любой символ, сложив его номер с указателем на саму строку, причём, нумеровать символы придётся с нуля.
Т.е. если нужно вернуть одну букву то return start[5] возвращает пятую букву, а если без индекса то всю строку начиная с символа на который он ссылается по условию.

Добавлено через 40 минут
Прочитал ещё раз про указатели и вот что нашёл:
"Если С++ компилятор обнаруживает строковый литерал,он сохраняет его в таблице строк программы и генерирует указатель на нужную строку."
Например:
char *ptr;
ptr="блаблабла";
При выполнении этого кусочка программы символы,образующие строковую константу,сохраняются в таблице строк,а переменной ptr присваивается указатель на соответствующую строку в этой таблице!
А если бы был массив то тогда(вернёмся к старому коду) start указывал на определённый символ(а не на строку),во как.
Правильно я понял это всё?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
24.01.2011, 12:08     Возвращение функциями указателей
Еще ссылки по теме:

Создать специализацию для шаблона, которая принимает массив указателей на строки и количество этих указателей C++
Создать специфицированный шаблон функции, принимающей массив указателей на char и количество самих указателей C++
C++ Возвращение char[]

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Nameless One
Эксперт С++
 Аватар для Nameless One
5754 / 3403 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
24.01.2011, 12:08     Возвращение функциями указателей #9
Цитата Сообщение от Rusl_v Посмотреть сообщение
При выполнении этого кусочка программы символы,образующие строковую константу,сохраняются в таблице строк,а переменной ptr присваивается указатель на соответствующую строку в этой таблице!
А если бы был массив то тогда(вернёмся к старому коду) start указывал на определённый символ(а не на строку),во как.
Дело в том, что указатель на char (т.е. char*) всегда указывает на какой-нибудь символ (естественно, если он инициализирован), несмотря на то, инициализирован он строковым литералом или нет. Дело в том, что переходя по смещению (или используя оператор взятия индекса), можно обращаться к символу, располагается в памяти следующим, и т.д. А если где-то дальше в памяти неслучайным образом еще и хранится нуль-терминатор, то область памяти от указателя до этого нуль-терминатора как раз-таки и составляет некоторую строку, с которой могут работать стандартные функции С (strlen, strcmp и т.д.).
Yandex
Объявления
24.01.2011, 12:08     Возвращение функциями указателей
Ответ Создать тему
Опции темы

Текущее время: 00:49. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru