Pomoc z funkcją / zamiana kodu z C++ na C/

0

Cześć, mam za zadanie sprawdzenie podzielności wprowadzanej liczby przez liczbę 11. Mam takie 2 programiki:

  1. Ten jest w C i działa ale tylko dla liczb do +-300, wyżej już zazwyczaj nie wskazuje prawidłowo. Co jest nie tak?

#include <stdio.h>

int parzyste(int n,int k)
{
    if(n<=0)
    {
        return 0;
    }
    else
    {
        int d=n/10;
        int ost=n-(d*10);
        if((k & 0x01)==0) return ost+parzyste(n/10,++k);
        return 0+parzyste(n/10,++k);
         
    }
}
int nie_parzyste(int n,int k)
{
    if(n<=0)
    {
        return 0;
    }
    else
    {
        int d=n/10;
        int ost=n-(d*10);
        if((k & 0x01)!=0)return ost+nie_parzyste(n/10,++k);
        return 0+nie_parzyste(n/10,++k);
         
    }
}
int przez_11(int n)
{
    if(n<=0)return 0;
    else return 1+przez_11(n/10);
}
int is_divisible_by_11(int number)
{
   if(number<0)
   {
     number=-number;
   }
    int roznica=nie_parzyste(number,0)-parzyste(number,0);
    if(roznica<0)roznica*=(-1);
    if(roznica==0)return 1;
    else return 0;
    return is_divisible_by_11(roznica);
}
int main() 
{
    printf("podaj tekst: ");
    int n;
    scanf("%d",&n);
    if(n<=0)
    {
      printf("Incorrect input\n");
      return 2;
    }
    if(is_divisible_by_11(n)==1) printf("YES");
    else printf("NO");
    return 0;
}
  1. Ten jest w C++ i działa ok, jednak mam problem z przetłumaczeniem go na C
#include <iostream>

void sum_odd_even(int value, int& odd_sum, int& even_sum)
{
    odd_sum += value - ((value / 10) * 10);
    value /= 10;
    if(value) 
    {
        sum_odd_even(value, even_sum, odd_sum);
    }
}
 
int is_divisible_by_11(int value)
{
    int odd_sum = 0;
    int even_sum = 0;
    sum_odd_even(value, odd_sum, even_sum);
    int diff = odd_sum - even_sum;
    diff = (diff < 0 ? -diff: diff);
    return (diff > 10 ? is_divisible_by_11(diff): !diff);
}
 
int main()
{
    int n;
    std::cin >> n;
    std::cout << (std::cin ? (is_divisible_by_11(n) ? "YES": "NO") : "Incorrect input") << '\n';
}

Z góry dzięki za pomoc.👍

1

Referencje w C++ pozwalają modyfikować oryginalne zmienne wrzucane do funkcji (lub metod).
edit: w przeciwnym wypadku operujesz (modyfikujesz, wykorzystujesz) jedynie na ich kopii.
W C nie ma referencji, ale zamiast nich używa się wskaźników:

void sum_odd_even(int value, int* odd_sum, int* even_sum)

Wewnątrz funkcji natomiast należy najpierw wyłuskać to, na co wskazują, również operatorem gwiazdki:

*odd_sum += value - ((value / 10) * 10);

Poczytaj więcej o wskaźnikach, w internecie jest tego naprawdę dużo.


Nie wiem tylko po co Ci argument int& even_sum przekazywany do void sum_odd_even(), skoro w tej funkcji w ogóle tego argumentu nie używasz?

1

Przecież kompilator wskazuje gdzie bład:

    if(roznica==0)return 1;
    else return 0;

i już dalej nić nie sprawdzasz.

0

Teraz mam takie coś i niestety dalej nie działa

#include <stdio.h>

int parzyste(int n,int k)
{
    if(n<=0)
    {
        return 0;
    }
    else
    {
        int d=n/10;
        int ost=n-(d*10);
        if((k & 0x01)==0) return ost+parzyste(n/10,++k);
        return 0+parzyste(n/10,++k);
         
    }
}
int nieparzyste(int n,int k)
{
    if(n<=0)
    {
        return 0;
    }
    else
    {
        int d=n/10;
        int ost=n-(d*10);
        if((k & 0x01)!=0)return ost+nieparzyste(n/10,++k);
        return 0+nieparzyste(n/10,++k);
         
    }
}
int przez_11(int n)
{
    if(n<=0)return 0;
    else return 1+przez_11(n/10);
}
int is_divisible_by_11(int number)
{
   if(number<0)
     number=-number;
    int roznica=nieparzyste(number,0)-parzyste(number,0);
    if(roznica<0)roznica*=(-1);
    if(roznica==0)return 1;
    else return 0;
    //return is_divisible_by_11(roznica);
}
int main() 
{
    printf("podaj tekst: ");
    int n;
    scanf("%d",&n);
    /*if(n<=0)
    {
      printf("Incorrect input\n");
      return 2;
    }*/
    if(is_divisible_by_11(n)==1) printf("YES");
    else printf("NO");
    return 0;
}
0

Ostatni return w wersji C w is_divisible_by_11 tak na oko nie ma prawa się wykonać, więc nie wiem jak to działa.
Może napisz do tego jakieś testy jednostkowe.

1

Nie naprawiłaś błąd tylko wywaliłaś potrzebną instrukcję.
W sumie całość jest bez sensu, trzy dzielenia razy ilość cyfr aby zastąpić jedną operację modulo? WTF?
Co innego gdyby liczba była ogromna (nie mieści się nawet w int64_t)
Wtedy funkcja powinna wyglądać zupełnie inaczej, coś w rodzaju:

int isDivisibleBy11(const char *number)
{
	long balance=0;
	for(int mul=1;*number;++number,mul=-mul)
	{
		balance+=mul*(*number-'0');
		if(balance>=11) balance-=11;
		else if(balance<=-11) balance+=11;
	}
	return !balance;
}

Jeżeli zaś koniecznie musisz robić to z liczbą to chociażby jedno dzielenie na cyfrę:

int isDivisibleBy11(long long number)
{
	if(number<0) number=-number;
	int balance=0,mul=1;
	for(long long next=number;number;number=next,mul=-mul)
	{
		balance+=mul*(number-10*(next=number/10));
		if(balance>=11) balance-=11;
		else if(balance<=-11) balance+=11;
	}
	return !balance;
}

Ale to powyższe jest ewidentnym bezsensem ponieważ to samo da się zapisać:

int isDivisibleBy11(long long number) { return !(number%11); }

I jeżeli ktoś wymusza na was takie zadania dydaktyczne to oznacza jedyne że ten ktoś nie zna się na dydaktyce.

0

Dokładnie taka jest treść zadania, więc niestety to co zaproponowałeś nie spełnia warunków

screenshot-20201209083607.png

0

Przerób podaną wersje iteracyjną na rekurencyjną i po kłopocie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1