Program nie liczy poprawnie dla liczby równej 0

0

Hej mam problem z działaniem programu.

Na wstępie pytanie czy jest jakaś różnica pomiędzy sprawdzaniem czy wskaźnik ==NULL czy wskaźnik==0 ?
Mój program nie liczy poprawnie dla liczby = 0;

Treść zadania:
Napisać program, który wykonuje operacje matematyczne (dodawanie, odejmowanie, mnożenie, dzielenie) na liczbach całkowitych wprowadzanych przez użytkownika. Program powinien wyświetlić w kolejnych liniach sumę, różnicę, iloczyn oraz iloraz wprowadzonych liczb, a w przypadku niemożliwości wykonania którejś z operacji, zamiast jej wyniku, program powinien wyświetlić komunikat "Error". Każda operacja powinna stanowić oddzielną funkcję, która zwraca wartość 1, gdy operacja została wykonana poprawnie, a 0 w przeciwnym wypadku. Prototypy funkcji powinny wyglądać następująco:

int add(const int *first, const int *second, int* result);
int subtract(const int *first, const int *second, int* result);
int multiply(const int *first, const int *second, int* result);
int divide(const int *first, const int *second, float* result);

KOD:

#include <time.h>
#include <stdlib.h>


int add(const int *first, const int *second, int* result);
int subtract(const int *first, const int *second, int* result);
int multiply(const int *first, const int *second, int* result);
int divide(const int *first, const int *second, float* result);
int main()
{
    int a=0;
    int b=0;
    int c=0;
    int *first=&a;
    int *second=&b;
   int  *result=&c;
    
    printf("\nPodaj pierwsza liczbe ");
    scanf("%d",first);
    printf("\nPodaj druga liczbe ");
    scanf("%d",second);
    
    add(first,second,result);
    subtract(first,second,result);
    multiply(first,second,result);
    divide(first,second,(float*)result);
}


int add(const int *first, const int *second, int* result)
{
    if(!*first || !*second)
    {
        printf("\nError");
        return 0;
    }
    else if(first==0 || second==0)
    
        {
            *result=*first+*second;
            printf("%d \n",*result);
            return 1;
        
    }
    else
    {
    *result=*first+*second;
        printf("%d \n",*result);
    return 1;
    }
}

int subtract(const int *first, const int *second, int* result)
{
    if(!*first || !*second)
    {
        printf("\nError");
        return 0;
    }
    else
    {
        *result=*first-*second;
          printf("%d \n",*result);
        return 1;
    }
}
int multiply(const int *first, const int *second, int* result)
{
    if(!*first || !*second)
    {
        printf("\nError\n");
        return 0;
    }
    else
    {
        *result=*first * *second;
          printf("%d \n",*result);
        return 1;
    }
}
int divide(const int *first, const int *second, float* result)
{
    if(!*first || !*second)
    {
        printf("Error\n");
        return 0;
    }
    
    else if( *second==0)
    {
        printf("Error\n");
        return 0;
    }
    else
    {
        *result=(float)*first / (float)*second;
          printf("%f \n",*result);
        return 1;
    }
}

Dzięki za pomoc

2

Dlaczego nie zezwalasz na dodawanie/odejmowanie i mnożenie zera/przez zero? Tylko zakaz dzielenia przez zero ma sens. Ponadto, choć nie jest to opisane bezpośrednio w zadaniu, wypisywanie nie powinno odbywać się w funkcjach wykonujących obliczenia. Po to zwracasz informację, czy operacja się udała. Dodatkowo, nie możesz zapisać wyniku dzielenia float do zmiennej typu int.

Na wstępie pytanie czy jest jakaś różnica pomiędzy sprawdzaniem czy wskaźnik ==NULL czy wskaźnik==0 ?

Nie. Nie wiem jaki to pytanie ma związek z resztą posta, nigdzie tego nie robisz.

0

Co do floata i int, to nie wiedziałem jak to obejść, ponieważ w 3 prototypach results przyjmuje typ int a w ostanim prototypie przyjmuje floata.

Co do głównego problemu.
To nie jest tak, że zrobiłem to celowo :/ w zadaniu miałem dać możliwość wprowadzenia wartości NULL do parametrów, stąd właśnie te if(!*first || !*second) "zabezpieczenia" które powodują moje problemy.

0

Przekaż wskaźnik do zmiennej typu float. Tak, musi to być inna zmienna.

if(!*first) nie sprawdza wartości wskaźnika, tylko wartość, na którą on wskazuje. Czyli sprawdzasz, czy podano 0, a nie czy wskaźnik jest nullem. if(!first || !second) do tego służy.

0

Ma to dużo sensu :)

W takim razie chyba ostanie pytanie " if(!first || !second)" to powinno zabezpieczać przed wprowadzeniem NULL to pierwszego bądź drugiego parametru, ale czemu sprawdza tylko dla pierwszego poprawnie?

0

Sprawdza poprawnie oba.

0

Coś nadal źle robie?

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

int add(const int* first, const int* second, int* result);
int subtract(const int* first, const int* second, int* result);
int multiply(const int* first, const int* second, int* result);
int divide(const int* first, const int* second, float* result);
int main()
{
    int a = 0;
    int b = 0;
    int c = 0;
    int* first = &a;
    int* second = &b;
    int* result = &c;

    printf("\nPodaj pierwsza liczbe ");
    scanf("%d", first);
    printf("\nPodaj druga liczbe ");
    scanf("%d", second);

    add(first, second, result);
    subtract(first, second, result);
    multiply(first, second, result);
    divide(first, second, (float*)result);
}

int add(const int* first, const int* second, int* result)
{
    if (!first || !second) {
        printf("\nError");
        return 0;
    }
    else if (first == 0 || second == 0)

    {
        *result = *first + *second;
        printf("%d \n", *result);
        return 1;
    }
    else {
        *result = *first + *second;
        printf("%d \n", *result);
        return 1;
    }
}

int subtract(const int* first, const int* second, int* result)
{
    if (!first || !second) {
        printf("\nError");
        return 0;
    }
    else {
        *result = *first - *second;
        printf("%d \n", *result);
        return 1;
    }
}
int multiply(const int* first, const int* second, int* result)
{
    if (!first || !second) {
        printf("\nError\n");
        return 0;
    }
    else {
        *result = *first * *second;
        printf("%d \n", *result);
        return 1;
    }
}
int divide(const int* first, const int* second, float* result)
{
    if (!first || !second) {
        printf("Error\n");
        return 0;
    }

    else if (*second == 0) {
        printf("Error\n");
        return 0;
    }
    else {
        *result = (float)*first / (float)*second;
        printf("%f \n", *result);
        return 1;
    }
}


1

Zobacz że w else if oraz else masz idealnie ten sam kod:

else if (first == 0 || second == 0)
{
	*result = *first + *second;
	printf("%d \n", *result);
	return 1;
}
else 
{
	*result = *first + *second;
	printf("%d \n", *result);
	return 1;
}
0

faktycznie, a czemu nadal nie sprawdza tych NULLi?

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

int add(const int* first, const int* second, int* result);
int subtract(const int* first, const int* second, int* result);
int multiply(const int* first, const int* second, int* result);
int divide(const int* first, const int* second, float* result);
int main()
{
    int a = 0;
    int b = 0;
    int c = 0;
    int* first = &a;
    int* second = &b;
    int* result = &c;

    printf("\nPodaj pierwsza liczbe ");
    scanf("%d", first);
    printf("\nPodaj druga liczbe ");
    scanf("%d", second);

    add(first, second, result);
    subtract(first, second, result);
    multiply(first, second, result);
    divide(first, second, (float*)result);
}

int add(const int* first, const int* second, int* result)
{
    if (!first || !second || !result) {
        printf("Error\n");
        return 0;
    }

    else {
        *result = *first + *second;
        printf("%d \n", *result);
        return 1;
    }
}

int subtract(const int* first, const int* second, int* result)
{
    if (!first || !second || !result) {
        printf("Error\n");
        return 0;
    }
    else {
        *result = *first - *second;
        printf("%d \n", *result);
        return 1;
    }
}
int multiply(const int* first, const int* second, int* result)
{
    if (!first || !second || !result) {
        printf("Error\n");
        return 0;
    }
    else {
        *result = *first * *second;
        printf("%d \n", *result);
        return 1;
    }
}
int divide(const int* first, const int* second, float* result)
{
    if (!first || !second || !result) {
        printf("Error\n");
        return 0;
    }

    else if (first != 0 && second == 0) {
        printf("Error\n");
        return 0;
    }
    else {
        *result = (float)*first / (float)*second;
        printf("%f \n", *result);
        return 1;
    }
}

0

Gdy ustawisz result na NULL to wszystko działa jak należy, co innego gdy first albo secondNULL, wtedy dochodzi do naruszenia ochrony pamięci dlatego że przekazujesz je do funkcji scanf() która ma pod ten adres wpisać odpowiednie wartości.

0

Niestety moja wiedza z zakresu programowania nie pozwala mi zrozumieć Twojej wypowiedzi :/
Da radę trochę jaśniej?

2

Zakładam że próbujesz zrobić coś takiego:

int* first = NULL;
int* second = NULL;
int* result = &c;

Program przestanie wykonywać się już na linii

scanf("%d", first);

dlatego że wskaźnik do scanf nie może być NULL a próba zapisania pod tym adresem (NULL) jakiejkolwiek wartości kończy się naruszeniem ochrony pamięci.

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