1

Тема: Функція із зміним числом параметрів

Задача: "1) Написати функцію sum() з змінним числом параметрів, що знаходить суму чисел типу int по формулі:         S=a1*a2+a2*a3+a3*a4+. . . . .
Написати функцію main(), що звертається до функції sum() не менш трьох разів.
"
Мій код:

Прихований текст
#include <iostream>
#include <stdio.h>
using namespace std;

int Sum(int a, ...)
{
    int *p = &a;
    ++p;
    int sum1;
    int sum = *p ;
    for (int i = 0; i < a; i++)
    {
        if (i == 0){
            sum = sum * p[i + 1];
        }
        else{
            sum1 = p[i] * p[i + 1];

            sum += sum1;

           
        }
    }
    return sum;

}
int main()
{
    int sum = Sum(6, 10, 15, 2, 3, 8, 29);
    cout << "Sum = " << sum << endl;

    return 0;
}

Писав код через vim компірівував через g++ . Виводить якийсь мусор, надіслав для подруги в неї visual studio в неї все працює добре.
Питання: в чому може бути проблема?

2 Востаннє редагувалося Betterthanyou (13.10.2015 21:55:08)

Re: Функція із зміним числом параметрів

Я трохи переробив вроді працює

int Sum(int a, ...)
{
    int *p = &a, sum=p[0];
    for (int i = 1; p[i] != 0; i++)
    {
        sum *= p[i];
    }
    return sum;

}
//
int sum = Sum(6, 10, 15, 2, 3, 8, 29,0);
Подякували: shonrens1

3 Востаннє редагувалося 0x9111A (13.10.2015 21:55:09)

Re: Функція із зміним числом параметрів

Скажіть подрузі нехай на Release переключить - теж буде мусор.
А мусор в p[i + 1] на останній ітерації. При Debug msvc все що можна зануляє от і не було видно.

Прихований текст

цикл зробіть до a-1, та й if той там не треба

Подякували: shonrens, koala2

4 Востаннє редагувалося Betterthanyou (13.10.2015 23:26:50)

Re: Функція із зміним числом параметрів

[delete]

5

Re: Функція із зміним числом параметрів

Betterthanyou написав:

Я трохи переробив вроді працює

int Sum(int a, ...)
{
    int *p = &a, sum=p[0];
    for (int i = 1; p[i] != 0; i++)
    {
        sum *= p[i];
    }
    return sum;

}
//
int sum = Sum(6, 10, 15, 2, 3, 8, 29,0);

Трохи не так. Бо має ще додавати, але дякую за старання))) Я помилку зрозумів зараз виправлю.

6 Востаннє редагувалося Betterthanyou (13.10.2015 22:59:31)

Re: Функція із зміним числом параметрів

shonrens написав:

Трохи не так. Бо має ще додавати, але дякую за старання))) Я помилку зрозумів зараз виправлю.

Вибач помилився 10, 15, 2, 3, 8, 29 ця послідовність має дорівнювати 531 ? так я зрозумів

int Sum(int a, ...)
{
    int *p = &a, sum = p[0] * p[1];
    for (int i = 1; p[i]!=0; i++)
    {
            if (p[i + 1] != 0)
            {
                sum += p[i] * p[i + 1];
            }
            else
            if (p[i + 1] == 0)
            {
                sum += p[i];
            }
    }
    return sum;

}
//
int sum = Sum(6, 10, 15, 2, 3, 8, 29,0);

або так

int Sum(int a, ...)
{
    int *p = &a, sum = p[0] * p[1];
    for (int i = 1; i<a; i++)
    {
        sum += p[i] * p[i + 1];        
    }
    sum += p[a];
    return sum;

}
//
int sum = Sum(6, 10, 15, 2, 3, 8, 29);

7 Востаннє редагувалося koala (13.10.2015 23:08:09)

Re: Функція із зміним числом параметрів

Можна навіть так:

int sum(int count, ...) {
  int res = 0;
  int *ptr = &count;
  while(--count) {
    ++ptr;
    res += *ptr * (*ptr+1);//можна навіть ризикнути і написати *ptr * *(++ptr), але це вже занадто
  }
  return res;
}

але це несерйозно, краще вже

#include <cstdarg> 
int sum( int count, ... ) {
  va_list args;
  va_start( args, count );
  int res = 0;
  int old = va_arg( args, int );
  while( --count ) {
    int new = va_arg( args, int );
    res += old * new;
    old = new;
  }
  va_end( args );
  return res;
}
Подякували: shonrens, Betterthanyou, 0x9111A, leofun014

8 Востаннє редагувалося shonrens (13.10.2015 23:09:15)

Re: Функція із зміним числом параметрів

Betterthanyou, 442 повино дорівнювати) Зараз спробую твій код.
Я пробував виводити цифри з якими оперую щось не зрозуміле звідки тільки береться
тут код

Прихований текст
/*"1) Написати функцію sum() з змінним числом параметрів, що знаходить суму чисел типу int по формулі:         S=a1*a2+a2*a3+a3*a4+. . . . .
Написати функцію main(), що звертається до функції sum() не менш трьох разів.
"*/
#include <iostream>
#include <stdio.h>

using namespace std;

int Sum(int a, ...)
{
    int *p = &a;
    ++p;
    int temp;
    int sum = *p;

    for (int i = 0; i < a; i++)

    {

        if (i == 0)
            cout << "p[1]: " << sum << endl;
            cout << "p[i + 1]: " << p[i + 1] << endl ;
            sum = sum * p[i + 1];
            cout << "sum: "  << sum << endl;
        if (i != 0 && i < a - 1){
            cout << "p[i] = " << p[i] <<  " ";
            cout << "p[i + 1] = " << p[i + 1] << endl;
            temp = p[i] * p[i + 1];
            cout << "temp: " << temp << endl;
            sum += temp;
        }
    }
    return sum;
}

int main()

        {

    int sum = Sum(6, 10, 15, 2, 3, 8, 29);
    cout << "Sum = " << sum << endl;

    return 0;
}

картинка прикріплена знизу.

Post's attachments

Знімок екрана з 2015-10-13 23:52:12.png 142.97 kb, 235 downloads since 2015-10-13 

9 Востаннє редагувалося shonrens (13.10.2015 23:20:32)

Re: Функція із зміним числом параметрів

koala написав:

Можна навіть так:

Прихований текст
int sum(int count, ...) {
  int res = 0;
  int *ptr = &count;
  while(--count) {
    ++ptr;
    res += *ptr * (*ptr+1);//можна навіть ризикнути і написати *ptr * *(++ptr), але це вже занадто
  }
  return res;
}

але це несерйозно, краще вже

Прихований текст
#include <cstdarg> 
int sum( int count, ... ) {
  va_list args;
  va_start( args, count );
  int res = 0;
  int old = va_arg( args, int );
  while( --count ) {
    int new = va_arg( args, int );
    res += old * new;
    old = new;
  }
  va_end( args );
  return res;
}

в другій частині ви використовуєте va_list,  va_start, va_arg... ми такого нажаль ще не вчили.
Спробував запустити приклад з вашої першої частини і ось результат, прикріпив.

Post's attachments

Знімок екрана з 2015-10-14 00:19:30.png 98.58 kb, 250 downloads since 2015-10-13 

10 Востаннє редагувалося Betterthanyou (13.10.2015 23:28:12)

Re: Функція із зміним числом параметрів

Я не зрозумів чому 442 я так рахував
S = 6*10+10*15+15*2+2*3+3*8+8*29+29 = 531
Якщо 442 то koala теж неправильно написав бо його функція рахує 440 (я про першу, другу не дивився)

11

Re: Функція із зміним числом параметрів

Betterthanyou написав:

Я не зрозумів чому 442 я так рахував
S = 6*10+10*15+15*2+2*3+3*8+8*29+29 = 531
Якщо 442 то koala теж неправильно написав бо його функція рахує 440

6 означає що чисел має бути 6, а 29 вже не потрібно додавати і виходить що 442ю

12 Востаннє редагувалося Betterthanyou (13.10.2015 23:34:48)

Re: Функція із зміним числом параметрів

442

int Sum(int a, ...)
{
    int *p = &a, sum=0;
    for (int i = 1; i<a; i++)
    {
        sum += p[i] * p[i + 1];        
    }
    return sum;
}

13 Востаннє редагувалося shonrens (13.10.2015 23:49:05)

Re: Функція із зміним числом параметрів

Betterthanyou написав:

442

int Sum(int a, ...)
{
    int *p = &a, sum=0;
    for (int i = 1; i<a; i++)
    {
        sum += p[i] * p[i + 1];        
    }
    return sum;
}

так само в мене виводить не те що потрібно...
Можливо я де інде роблю помилку і просто її не бачу.

Прихований текст
#include <iostream>
#include <stdio.h>

using namespace std;

    int Sum(int a, ...)
    {
        int *p = &a, sum=0;
        for (int i = 1; i<a; i++)
        {
        cout << "p[i] = " << p[i] << endl;
            sum += p[i] * p[i + 1];
        }
        return sum;
    }

int main()

        {

    int sum = Sum(6, 10, 15, 2, 3, 8, 29);
    cout << "Sum = " << sum << endl;

    return 0;
}
Post's attachments

Знімок екрана з 2015-10-14 00:44:29.png 100.2 kb, 198 downloads since 2015-10-13 

14

Re: Функція із зміним числом параметрів

shonrens написав:

Я пробував виводити цифри з якими оперую щось не зрозуміле звідки тільки береться
тут код

Ви забули душки фігурні поставити {}

int Sum(int a, ...)
{
    int *p = &a;
    ++p;
    int temp;
    int sum = *p;

    for (int i = 0; i < a; i++)

    {

        if (i == 0)
        {
            cout << "p[1]: " << sum << endl;
            cout << "p[i + 1]: " << p[i + 1] << endl;
            sum = sum * p[i + 1];
            cout << "sum: " << sum << endl;
        }
        if (i != 0 && i < a - 1) {
            cout << "p[i] = " << p[i] << " ";
            cout << "p[i + 1] = " << p[i + 1] << endl;
            temp = p[i] * p[i + 1];
            cout << "temp: " << temp << endl;
            sum += temp;
        }
    }
    return sum;
}
Post's attachments

Unпрарпtitled.png 6.42 kb, 188 downloads since 2015-10-13 

Подякували: shonrens1

15

Re: Функція із зміним числом параметрів

shonrens написав:

так само в мене виводить не те що потрібно...

В мені не g++ тому не знаю в чому проблема, можливо попробуйте масивом передати ті числа

int Sum(int *p)
{
    int sum = 0;
    for (int i = 1; i<p[0]; i++)
    {
        sum += p[i] * p[i + 1];
    }
    return sum;
}

//
    int arr[] = { 6, 10, 15, 2, 3, 8, 29 };
    int sum = Sum(arr);

16 Востаннє редагувалося shonrens (13.10.2015 23:55:22)

Re: Функція із зміним числом параметрів

Betterthanyou написав:
shonrens написав:

так само в мене виводить не те що потрібно...

В мені не g++ тому не знаю в чому проблема, можливо попробуйте масивом передати ті числа

int Sum(int *p)
{
    int sum = 0;
    for (int i = 1; i<p[0]; i++)
    {
        sum += p[i] * p[i + 1];
    }
    return sum;
}

//
    int arr[] = { 6, 10, 15, 2, 3, 8, 29 };
    int sum = Sum(arr);

Дякую, мб відправлю як є, а там вже  розпитаю у викладача. Бо потрібно зробити через  функцію із зміним числом параметрів

17

Re: Функція із зміним числом параметрів

Гм... цікаво. Згенерував ассемблерний код - виявляється, gcc інлайнить цю функцію, що повністю псує її роботу.

Прихований текст
_main:
    leal    4(%esp), %ecx
    andl    $-16, %esp
    pushl    -4(%ecx)
    pushl    %ebp
    movl    %esp, %ebp
    pushl    %ecx
    subl    $36, %esp
    call    ___main
    movl    -8(%ebp), %edx
    movl    -4(%ebp), %eax
    leal    1(%edx), %ecx
    imull    %ecx, %edx
    leal    1(%eax), %ecx
    imull    %ecx, %eax
    addl    %eax, %edx
    movl    0(%ebp), %eax
    leal    1(%eax), %ecx
    imull    %ecx, %eax
    addl    %eax, %edx
    movl    4(%ebp), %eax
    leal    1(%eax), %ecx
    imull    %ecx, %eax
    addl    %eax, %edx
    movl    8(%ebp), %eax
    leal    1(%eax), %ecx
    imull    %ecx, %eax
    movl    $__ZSt4cout, %ecx
    addl    %edx, %eax
    movl    %eax, (%esp)
    call    __ZNSolsEi
    movl    -4(%ebp), %ecx
    xorl    %eax, %eax
    subl    $4, %esp
    leave
    leal    -4(%ecx), %esp
    ret
Подякували: shonrens1

18

Re: Функція із зміним числом параметрів

Рішення (для gcc):

int __attribute__ ((noinline)) sum(int count, ...) {

Більш загальне рішення: не користуватися цією фічею, вона небезпечна :)

Подякували: shonrens, Arete2

19

Re: Функція із зміним числом параметрів

koala написав:

Рішення (для gcc):

int __attribute__ ((noinline)) sum(int count, ...) {

Більш загальне рішення: не користуватися цією фічею, вона небезпечна :)

Дякую, завтра спробую і відпишу.