Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/6: Рейтинг темы: голосов - 6, средняя оценка - 4.50
Higher
1953 / 1219 / 120
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
1

Функции и указатели

03.06.2011, 18:47. Показов 1132. Ответов 17
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Второй нубский вопрос за день.
До сегодняшнего дня вполне успешно пользовался 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;
}
В мейне копирование происходит нормально, а в функции не хочет... Пробовал разными способами. Подозреваю, что дело в указателях, с которыми я не так сильно дружу, как хотелось бы...
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
03.06.2011, 18:47
Ответы с готовыми решениями:

Указатели на функции. Указатели на функции как формальные параметры у функциях высшего уровня
Найти наименьшее значение для функций используя функции и указатели на функции ...

Указатели и массивы. Указатели и функции
Никак не разберусь с указателями на функцию. Пишу в Visual Studio. Надо написать функцию...

Указатели на массивы. Указатели и функции
Вот задача: Даны два массива : А и B. Необходимо создать третий массив, в котором нужно...

Объявить массив из N указателей на функции, возвращающих указатели на функции, возвращающие указатель на char
Задание: Объявить массив из N указателей на функции, возвращающих указатели на функции,...

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

Добавлено через 51 секунду
Цитата Сообщение от diagon Посмотреть сообщение
(хотя догадываюсь, что возвращает конец строки)
хм..верно, протупил)
0
Higher
1953 / 1219 / 120
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
03.06.2011, 19:08  [ТС] 9
Цитата Сообщение от Maxwe11 Посмотреть сообщение
и зачем реверс делаешь?
Я потрошу int с конца, поэтому в строку заносится перевернутое значение.
0
187 / 174 / 18
Регистрация: 22.03.2010
Сообщений: 612
03.06.2011, 19:19 10
ввёл я qwerty. Когда дотрассировал до строки
Цитата Сообщение от diagon Посмотреть сообщение
return str_cpy(str, str_rev(str))
первый аргумент - "erty"
второй аргумент - "ytre"
0
Higher
1953 / 1219 / 120
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
03.06.2011, 19:23  [ТС] 11
Мм... Функция ведь принимает int, затем потрошит его с конца, в итоге там лежит перевернутое значение. Должна возвращать нормальное... Как туда можно вбивать строку?
Сама str_cpy должна правильно работать, эта строчка
C++
1
while(*to++=*from++);
Взята из книги Страструпа
0
49 / 49 / 14
Регистрация: 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 );
0
Higher
1953 / 1219 / 120
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
03.06.2011, 19:52  [ТС] 13
Безрезультатно=(
Я по разному их крутил, вставлял возвращаемое значение и вызывал как войдовую, итог 1...
Сейчас поставил вывод строки перед return... Там вообще что-то левое, непонятно, как перевернутая строка выводится вообще.
0
49 / 49 / 14
Регистрация: 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
1
Higher
1953 / 1219 / 120
Регистрация: 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;
Видимо я как-то криво потрошу число, т.к. после этого цикла ничего похожего на введенное число в строке нету.
0
Higher
1953 / 1219 / 120
Регистрация: 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);
}
Ничего кроме мусора не выводится
И тем не менее, каким-то образом, возвращается значение перевернутой строки!
...
Есть сильное подозрение, что этот указатель указывает на что-то очень левое... Хотя тогда была бы ошибка сегментации...
...Я окончательно запутался... Указателям я не понравился, они надо мной издеваются(см. вложение)...
Функции и указатели
0
Higher
1953 / 1219 / 120
Регистрация: 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
}
Почему ошибка? Постфиксный инкремент есть, а префиксного нету? о_О
0
5231 / 3204 / 362
Регистрация: 12.12.2009
Сообщений: 8,116
Записей в блоге: 2
04.06.2011, 17:12 18
Цитата Сообщение от diagon Посмотреть сообщение
И на последок 2 небольших вопроса.
1)Потому что указатель на char инициализируется указателем на const char, а значит через указатель на char можно менять то, что по идеи const char. А так делать нельзя, на то он и const. (это можно сделать через приведение типа и надеятся на удачу))
2)Потому как нужно писать так *++str, а в том виде как у тебя, ты пытаешься изменить то, что находится по указателю, т.е. const char.
1
04.06.2011, 17:12
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.06.2011, 17:12
Помогаю со студенческими работами здесь

Используя указатели на функцию вычислить значение функции в точке х в соответствии с выбором функции
Используя указатели на функцию вычислить значение функции в точке х в соответствии с выбором...

Используя указатели на функцию вычислить значение функции в точке х в соответствии с выбором функции
Используя указатели на функцию вычислить значение функции в точке х в соответствии с выбором...

Используя указатели на функцию вычислить значение функции в точке X в соответствии с выбором функции пользователем
Решил выложить свои лабораторные работы 1-10 за первый курс, первого семестра...

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


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

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru