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

Функции и указатели - C++

Восстановить пароль Регистрация
 
diagon
Higher
 Аватар для diagon
1920 / 1186 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
03.06.2011, 18:47     Функции и указатели #1
Второй нубский вопрос за день.
До сегодняшнего дня вполне успешно пользовался STL-овскими стрингами, сейчас наткнулся в книге Страуструпа на задание - написать свои аналоги функций из string.h, а также реализовать atoi и itoa. Посидел, поизобретал велосипед... Но на itoa застопорился=\
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <cstdio>
unsigned str_len(const char * str){
        int i=-1;
        while (str[++i]);
        return i; 
}
int atoi(const char * str){
    int num=0,i=0;
    bool _=false;
    if (*str=='-') {++i; _=true;}
    for (; str[i];num+=str[i++]-48)
        num*=10;        
    return (_)?-num:num;    
}
char * str_rev(const char * str){ //это вроде работает,но критика приветствуется
    unsigned len=str_len(str);
    char * newstr=new char[len], *_= newstr;   
    while (len)
        *_++=str[--len];
    *_= 0;
    return newstr;  
}
char * str_cpy(char * to, const char * from){
        char * x=to;
        while(*to++=*from++);  
        return x;  
}
char * itoa(int num,char * str,int base){ 
    bool _=false;
    if (num < 0) {_=true; num*=-1;}
    for(;num;num/=base)
        *str++=num%base+48;
    if (_) *str='-'; //теперь в стринге лежит перевернутое число
    return str_cpy(str, str_rev(str)); //а вернуть нормальное не получается
}
 
    
int main(){
    const int size=100;
    char s[size],s1[size];
    int x;
    scanf("%s",s); //123
    printf("%s == %s\n",s,str_cpy(s1,s)); //123 == 123
    scanf("%d",&x); //123
    itoa(x,s,10);
    printf("%d -> %s\n",x,s); //123 -> 321
    return 0;
}
В мейне копирование происходит нормально, а в функции не хочет... Пробовал разными способами. Подозреваю, что дело в указателях, с которыми я не так сильно дружу, как хотелось бы...
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.06.2011, 18:47     Функции и указатели
Посмотрите здесь:

C++ Указатели на функции
Функции и указатели C++
C++ Шаблонные функции и указатели на функции
Указатели на Функции C++
C++ функции, указатели
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Jupiter
Каратель
Эксперт C++
6543 / 3963 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
03.06.2011, 18:54     Функции и указатели #2
а память кто будет освобождать в char * str_rev(const char * str) ?
diagon
Higher
 Аватар для diagon
1920 / 1186 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
03.06.2011, 18:55  [ТС]     Функции и указатели #3
А как ее после return освободить?о_О
Но вопрос не в этом...
kjahert
48 / 48 / 5
Регистрация: 08.04.2011
Сообщений: 124
03.06.2011, 19:02     Функции и указатели #4
diagon, Ты имеешь в виду, что не выводит 123==123 и 123->321?
diagon
Higher
 Аватар для diagon
1920 / 1186 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
03.06.2011, 19:02  [ТС]     Функции и указатели #5
Нет, это то, что выводит.
Хочу, чтобы вывелось
123==123
123->123
Jupiter
Каратель
Эксперт C++
6543 / 3963 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
03.06.2011, 19:03     Функции и указатели #6
попробуй так
C
1
2
3
4
char * str_cpy(char * to, const char * from){
        while(*to++=*from++);  
        return to;  
}
diagon
Higher
 Аватар для diagon
1920 / 1186 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
03.06.2011, 19:06  [ТС]     Функции и указатели #7
Я так изначально делал, но т.к. по неведомым мне причинам это не работало(хотя догадываюсь, что возвращает конец строки), то сделал, как в первом посте.
Если вставить эту функцию, то вывод
123 ==
123 -> 321(о_О)
Трассировщика к сожалению нету, линуксовым дебагером пользоваться пока не умею.
Jupiter
Каратель
Эксперт C++
6543 / 3963 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
03.06.2011, 19:08     Функции и указатели #8
Цитата Сообщение от diagon Посмотреть сообщение
return str_cpy(str, str_rev(str)); //а вернуть нормальное не получается
и зачем реверс делаешь?

Добавлено через 51 секунду
Цитата Сообщение от diagon Посмотреть сообщение
(хотя догадываюсь, что возвращает конец строки)
хм..верно, протупил)
diagon
Higher
 Аватар для diagon
1920 / 1186 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
03.06.2011, 19:08  [ТС]     Функции и указатели #9
Цитата Сообщение от Maxwe11 Посмотреть сообщение
и зачем реверс делаешь?
Я потрошу int с конца, поэтому в строку заносится перевернутое значение.
pito211
 Аватар для pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
03.06.2011, 19:19     Функции и указатели #10
ввёл я qwerty. Когда дотрассировал до строки
Цитата Сообщение от diagon Посмотреть сообщение
return str_cpy(str, str_rev(str))
первый аргумент - "erty"
второй аргумент - "ytre"
diagon
Higher
 Аватар для diagon
1920 / 1186 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
03.06.2011, 19:23  [ТС]     Функции и указатели #11
Мм... Функция ведь принимает int, затем потрошит его с конца, в итоге там лежит перевернутое значение. Должна возвращать нормальное... Как туда можно вбивать строку?
Сама str_cpy должна правильно работать, эта строчка
C++
1
while(*to++=*from++);
Взята из книги Страструпа
kjahert
48 / 48 / 5
Регистрация: 08.04.2011
Сообщений: 124
03.06.2011, 19:46     Функции и указатели #12
34 строка, поменяй
C++
1
return str_cpy(str, str_rev(str))
на
C++
1
return str_cpy(str_rev(str),str );
diagon
Higher
 Аватар для diagon
1920 / 1186 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
03.06.2011, 19:52  [ТС]     Функции и указатели #13
Безрезультатно=(
Я по разному их крутил, вставлял возвращаемое значение и вызывал как войдовую, итог 1...
Сейчас поставил вывод строки перед return... Там вообще что-то левое, непонятно, как перевернутая строка выводится вообще.
kjahert
48 / 48 / 5
Регистрация: 08.04.2011
Сообщений: 124
03.06.2011, 20:01     Функции и указатели #14
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <stdio.h>
unsigned str_len(char * str){
        int i=-1;
        while (str[++i]);
        return i; 
}
int atoi(char * str){
        int num=0,i=0;
        int _=0;
        if (*str=='-') {++i; _=1;}
        for (; str[i];num+=str[i++]-48)
                num*=10;                
        return (_)?-num:num;    
}
char * str_rev(char * str){
        unsigned len=str_len(str);
        char * newstr=new char[len], *_= newstr;   
        while (len)
                *_++=str[--len];
        *_= 0;
        return newstr;  
}
char * str_cpy(char * to, char * from){
        char * x=to;
        while(*to++=*from++);  
        return x;  
}
char * itoa(int num,char * str,int base){ 
        int _=0;
        if (num < 0) {_=1; num=1;}
    for(;num;num/=base)
                *str=num%base+48;
        if (_) *str='-'; //теперь в стринге лежит перевернутое число
    return str_cpy(str_rev(str),str ); //а вернуть нормальное не получается
}
 
        
int main(){
        const int size=100;
        char s[size],s1[size];
        int x;
        scanf("%s",s); //123
        printf("%s == %s\n",s,str_cpy(s1,s)); //123 == 123
        scanf("%d",&x); //123
    itoa(x,s,10);
        printf("%d -> %s\n",x,s); //123 -> 321
        return 0;
}
Странно, у меня в bc3.1 работает нормально 123==123, 123->123
diagon
Higher
 Аватар для diagon
1920 / 1186 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
03.06.2011, 20:56  [ТС]     Функции и указатели #15
о_О у меня тоже... Но я там еще что-то накрутил, сейчас буду смотреть, в чем была ошибка.

Добавлено через 9 минут
А дело-то было в этой строке...
C++
1
*str++=num%base+48;
Если убрать инкремент у указателя, то все работает. Но почему? Как он сам себя инкрементирует? о_О

Добавлено через 42 минуты
Не, ну это уже мистика какая-то!
Был такой мейн
C++
1
2
3
4
5
6
7
8
9
10
11
int main(){
        const int size=100;
        char s[size],s1[size];
        int x;
        scanf("%s",s); //123
        printf("%s == %s\n",s,str_cpy(s1,s)); //123 == 123
        scanf("%d",&x); //123
        itoa(x,s,10);
        printf("%d -> %s\n",x,s); //123 -> 123
        return 0;
}
Стал такой
C++
1
2
3
4
5
6
7
8
9
int main(){
    const int size=10;
    char s[size];
    int x;
    scanf("%d",&x); //123
    itoa(x,s,10);
    printf("%d -> %s\n",x,s); //123 -> 1
    return 0;
}
Теперь выводится одна цифра...
...
Понятно почему работало раньше - вбивалось одно и тоже число, а так как инкремента у указателя не было, то оно не менялось. Также примерно известно где ошибка.
C++
1
2
for(;num;num/=base)
      *str++=num%base+48;
Видимо я как-то криво потрошу число, т.к. после этого цикла ничего похожего на введенное число в строке нету.
diagon
Higher
 Аватар для diagon
1920 / 1186 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
03.06.2011, 21:19  [ТС]     Функции и указатели #16
Вставил я туда 2 отладочных цикла, получилось так
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
char * itoa(int num,char * str,int base){ 
    for (int j=0; j < 10; j++)
    printf("\n%c - %d\n",str[j],str[j]);
    printf("--------------------------------------------\n");
    bool _=false;
    if (num < 0) {_=true; num*=-1;}
    for(;num;num/=base)
        *str++=num%base+48;
    if (_) *str++='-';
    *str=0;
    for (int j=0; j < 10; j++)
      printf("\n%c - %d\n",str[j],str[j]);
    return str_cpy(str_rev(str),str);
}
Ничего кроме мусора не выводится
И тем не менее, каким-то образом, возвращается значение перевернутой строки!
...
Есть сильное подозрение, что этот указатель указывает на что-то очень левое... Хотя тогда была бы ошибка сегментации...
...Я окончательно запутался... Указателям я не понравился, они надо мной издеваются(см. вложение)...
Функции и указатели
diagon
Higher
 Аватар для diagon
1920 / 1186 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
04.06.2011, 14:20  [ТС]     Функции и указатели #17
Блин, вроде проверял, а ошибка была глупой...
C++
1
2
3
4
5
6
7
8
9
10
char * itoa(int num,char * str,int base){ 
    char * res=str;
    bool _=false;
    if (num < 0) {_=true; num*=-1;}
    for(;num;num/=base)
        *str++=num%base+48;
    if (_) *str++='-';
    *str=0;
    return str_cpy(res,str_rev(res));
}
Вот так почти работает, только нуль почему то не хочет.
Ошибка, как я понял, была в том, что я возвращал указатель на конец строки. Теперь возвращается указатель на начало

Добавлено через 7 минут
Теперь работает и с нулем
C++
1
2
3
4
5
6
7
8
9
10
11
char * itoa(int num,char * str,int base){ 
    char * res=str;
    if (!num) {*str++=48; *str=0; return res;}  //за счет этой строки
    bool _=false;
    if (num < 0) {_=true; num*=-1;}
    for(;num;num/=base) //если num=0, то цикл ни разу не выполнится 
        *str++=num%base+48;
    if (_) *str++='-';
    *str=0;
    return str_cpy(res,str_rev(res));
}
Добавлено через 1 час 53 минуты
Переделал atoi, теперь работает с восьмеричной, десятичной, и шестнадцатеричной системой счисления. Вот код, возможно понадобится кому-нибудь=)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int atoi(const char * str){
    int base,res=0;
    bool _=false;
    if (*str=='-') {*str++; _=true;}
    if (*str==48){
        *str++;
        switch(*str){
            case 0:return 0;
            case 'x':base=16; *str++; break;
            default:base=8;
        }
    }
    else base=10;
    char x=(base==16)?'7':'0';
    for(;*str;res+=(*str++-x))
        res*=base;
    return (_)?-res:res;
}
----------------------------------------------------------------------------------------------------------------------
И на последок 2 небольших вопроса.
1)
const char * - это ведь указатель на константу, а не константный указатель на char?
В таком случае, почему нельзя сделать так
C++
1
2
3
void func(const char * str){
    char * ptr=str;  //error
}
2)
C++
1
2
3
4
void func(const char * str){
    *str++;
    ++*str; //error
}
Почему ошибка? Постфиксный инкремент есть, а префиксного нету? о_О
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.06.2011, 17:12     Функции и указатели
Еще ссылки по теме:

C++ Функции и указатели
C++ Распечатать таблицы значений функций cox (x) и на отрезке [a; b] с шагом h, развив функции в ряд Тейлора и используя указатели на функции
Указатели на функции C++

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

Или воспользуйтесь поиском по форуму:
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4237 / 2770 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
04.06.2011, 17:12     Функции и указатели #18
Цитата Сообщение от diagon Посмотреть сообщение
И на последок 2 небольших вопроса.
1)Потому что указатель на char инициализируется указателем на const char, а значит через указатель на char можно менять то, что по идеи const char. А так делать нельзя, на то он и const. (это можно сделать через приведение типа и надеятся на удачу))
2)Потому как нужно писать так *++str, а в том виде как у тебя, ты пытаешься изменить то, что находится по указателю, т.е. const char.
Yandex
Объявления
04.06.2011, 17:12     Функции и указатели
Ответ Создать тему
Опции темы

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