LINUX.ORG.RU

Указатель на функцию

 ,


0

1

Всем привет, возникла тут непонятная ситуация, и, может быть, кто-нибудь поможет разобраться, буду очень признателен. Проблема связана с указателем на void, преобразованием и указателем на функцию, основные моменты:

void add_num(void *, void *);
void add_str(char *a, char *b);


void (*p)(void*,void*);

if (number) {
    p = &add_num;
} else {
    p = &add_str;
}

Ну и, соответственно, проблема в том, что в 'p = &add_num;' все нормально, потому что указатели на void, сама функция:

void add_num(void *a, void *b) {
    int one, two, result;
    char *c = a;
    char *d = b;
    
    
    printf("Test2, %s:%s\n", c, d);
    one = atoi(c);
    two = atoi(d);
    result = one+two;
    printf("Result = %d\n", result);
    
    itoa(result, r);
}
Тут мы получаем void, переприсваиваем в 'char *' и все работает.

А вот в случае с 'p = &add_str;' Я получаю вот это:

'main.c:38:11: warning: assignment from incompatible pointer type [enabled by default]'

Ну и собственно мой вопрос - программа-то работает, но как избавиться от этого сообщения и что вообще не так? Можно, конечно, сделать так же как и с 'p = &add_num;', но должен же быть и другой путь? Ну и весь код программы:

#include <stdio.h>
#include <stdlib.h>

void add_num(void *, void *);
void add_str(char *a, char *b);
void itoa(int i, char f[]);
void reverse(char rline[]);
char r[200];

int main(int argc, char **argv) {
    char c, number;
    void (*p)(void*,void*);

    number = 0;
    printf("Testing\n");
    printf("%s and %d\n", argv[1], argc);
    
    while ( --argc > 0 && ( **++argv == '-') ) {
        while ( (c = *++argv[0]) ) {
            printf("Test c=%c\n", c);
            switch(c) {
            case 'n':
                number=1;
                break;
            default:
                printf("Please enter valid key\n");
            }
            
        }
    }
    
    /* argv[2] argv[3] */
    printf("Number = %d\n", number);
    
    if (number) {
        p = &add_num;
    } else {
        p = &add_str;
    }
    
    
    
    (*p)((void *)argv[0], (void*)argv[1]);
    printf("test1: %s:%s\n", argv[0], argv[1]);
    /* add_num(argv[0], argv[1]); */
    
    printf("Finally result = %s\n", r);
    
    

    return 0;
}


void add_num(void *a, void *b) {
    int one, two, result;
    char *c = a;
    char *d = b;
    
    
    printf("Test2, %s:%s\n", c, d);
    one = atoi(c);
    two = atoi(d);
    result = one+two;
    printf("Result = %d\n", result);
    
    itoa(result, r);
}


void itoa(int n, char s[]) {
    int i = 0;
    int sign;
    //for (i = 0; i < 5;s[i++] = 5 + '0')
    //sign = ( n < 0) ? -1: 1;
    if ( ( sign = n )  < 0)
        n = -n;
    //printf("%d\n", sign);
    
    if ( sign < 0 )
        i++;
    //printf("%d\n", i);
    do {
        //s[i++] = n % 10 - '0';
        //n /= 10;
        s[i++] = n%10 +'0';
        //n /= 10;
        //printf("%d\n", s[i - 1]);
        
    //} while ( n > 0);
    } while ( ( n/=10 ) > 0 );
    
    if (sign < 0)
        s[i++] = '-';
    s[i] = '\0';
    
    
    
    //printf("%d\n", sign);
};


void reverse(char rline[])
{
  int i,j;
  char temp;

  for(i=0;rline[i]!='\0';++i)
    ;
  --i;
  if(rline[i]=='\n')
  --i;

  j = 0;

  while(j < i)
  {
    temp = rline[j];
    rline[j] = rline[i];
    rline[i] = temp;
    --i;
    ++j;
  }
}

void add_str(char *a, char *b) {
    int i;
    i = 0;
    
    while ( *a != '\0' ) {
        r[i++] = *a;
        a++;
    }
    
    /* if ( *a == '\0')
        i++; */
    while (*b != '\0') {
        printf("Test5: %s\n", b);
        r[i++] = *b;
        b++;
    }
    
}

Ответ на: комментарий от Kronick

K&R и все такое, если они так сделали книжку, в таком порядке, то на то явно есть причина.

Ну, началось. А если завтра тебе драгонбук или taocp предложат читать? А из окна прыгнуть?

anonymous
()
Ответ на: комментарий от anonymous

У меня есть план и я его придерживаюсь. Вот захотел выучить С - взял книжку и учусь по ней, что плохого?

Kronick
() автор топика
Ответ на: комментарий от Kronick

Плохого то, что не подвергаешь сомнению «авторитеты». Такими темпами вырастешь в гнусного мудака, который будет топить за «философию юникс» ну или там за сиплюсплюс какой-нибудь.

anonymous
()
Ответ на: комментарий от anonymous

Как по мне гнусные мудаки - это как раз те, кто в самом начале обучения споря со всеми, везде лезут со своим мнением, когда ничерта не понимают. Много детей в школе спорят с учителем когда им говорят что 2*2=4? Я же учу саму основу языка, синтаксис, я прекрасно знаю что такое учебный план и зачем нужен определенный порядок в изучении чего-то. Если его не соблюдать - то вполне можно нахвататься обрывочных знаний всего подряд и вырасти говнокодером. Я же хочу получить базу в полном объеме, в K&R она есть и она хорошо структурирована, я в этом уже убедился. А вот когда буду знать это - там уже буду делать что-то сам и понимать где правильно, а где нет.

Kronick
() автор топика
Ответ на: комментарий от Kronick

Желаю тебе все таки раздавить в себе личинку школьной училки/вертухая. А нет - ну что ж, ждем твоих постов про фейлософию юнегз.

Привет.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.