0

I`m trying to get the sum of two arrays using pointers, but when the output comes all are zeros, what can I do?

And please if there a better way to do it I would like to know

Here`s the code

UPDATE

#include  < cstdio >  
#include < iostream >

using namespace std;

unsigned i;

int main(){

/* Array`s input */

    short A[3];

    for( i = 0 ; i < 3 ; i++ ){

    printf("Insert number for [A]: ");
    scanf("%hd",&A[i]);

    }

    printf("\n");

    short B[3];

    for( i = 0 ; i < 3 ; i++ ){

    printf("Insert number for [B]: ");
    scanf("%hd",&B[i]);

    }

    short C[3];

// Pointers

    short *punt_A, *punt_B, *punt_C;

    punt_A = &A[0];
    punt_B = &B[0];
    punt_C = &C[0];

// Addition

    for( i = 0 ; i < 3 ; i++ ){

    C[i]=punt_A[i]+punt_B[i];

    }

    printf("\n\nArray addition = { %d, %d, %d }\n", *punt_C, *(punt_C + 1), *(punt_C + 2));



return 0;

}
6
  • Why didn't you print out the result of the arrays first, so that we can know what your real intentions are with the pointers? Also, why write a tricky loop like this: for( i = 3; i-- ; ) What's wrong with simply for(int i = 0; i < 3; ++i )? Commented May 21, 2016 at 1:20
  • 1
    scanf("%d",&A[i]); %hd for short --> scanf("%hd",&A[i]); Commented May 21, 2016 at 1:24
  • 3
    This post is a wonderful example of trying to be clever and outwitting yourself. Commented May 21, 2016 at 1:24
  • regarding this line: # include < stdio.h >, since this code is for C++, the line should be: # include < cstdio > Commented May 21, 2016 at 1:25
  • If you used C++'s cin, stopped trying to outwit yourself (thanks @Hurkyl) writing weird loop constructs, you would have at least a chance to get to the pointer section without undefined behavior from occurring. Commented May 21, 2016 at 1:26

4 Answers 4

2

Remember short A[3]; will allow you to legally access A[0]..A[2]

In

for( i = 3; i-- ; )
{
/* i-- is a tricky way of entering the loop
 * This checks i for the condition, and passes (i-1, the current value
 * of i) to the loop
 * Though the method is smart I think it is less readable
 * There is no access violation here, forgive my previous comment :(
 */
printf("Insert number for [A]: ");
scanf("%hd",&A[i]);  // Remember %hd for short.

}

Addition here may be better represented as :

for( i = 0; i<3;i++){ 
/* I changed the forloop structure which may be used 
 * for reading the arrays too. In fact this has no surprises.
 */
C[i]=punt_A[i]+punt_B[i]; // Or *(punt_A+i) + *(punt_B+i)

}

Regarding,

printf("\n\nArray addition = { %d, %d, %d }\n", *punt_A, *punt_B, *punt_C );

This prints only A[0],B[0],C[0] respectively and your format specifier "%d" doesn't match the type short. The right specifier is "%hd". Print the result array using a loop.

Sign up to request clarification or add additional context in comments.

6 Comments

The loop does not access A[3]
@sjsam See the condition in the for loop, it's executed before the body, hence A[2] is the 1st index accessed.
@πάνταῥεῖ : thankyou for the f/b. I thought since i-- is postfix the previous value of i would go inside the loop body and forgot the fact that condition itself makes a sequence point. Anyway I think the forloop style is bad. Updating the answer in a moment :)
@M.M : Updated the answer, thanks for the feedback. :)
I'm pretty sure shorts get upgraded to ints when passed as parameters like that, so %d is correct.
|
1

punt_A, punt_B, punt_C are all left pointing one element past the end of their respective arrays, eg punt_A is now pointing at A[3]. The arrays are allocated on the stack along word boundaries, so there is "dead space" after each array on the stack. In a Windows debug build, uninitialised areas are marked with 0xcccccccc so I see -13108 which is (short)(0xcccccccc). In a release build, you just see whatever was left in that memory address from before, which in many cases is just zero.

I did a double take when I saw for (i = 3; i--; ). You've put i-- where the check condition normally goes. It's clearer to use for (i = 2; i >= 0; i--; ). It does actually work by accident because when the condition i-- is evaluated, it takes the i and checks whether that condition is nonzero. After the check, i gets decremented and enters the loop. When i becomes zero, the loop terminates. So inside the loop you see i = 2, 1, 0. The post-decrement operator is applied after any evaluations, eg, if int n = 1; then n + n--; returns 2, not 1. n is decremented after the expression is evaluated.

3 Comments

for (i = 2; i >= 0; i--; ) breaks if i is unsigned, unlike OP's version
True! for (i = 0; i < 3; i++;) is better as it works for signed or unsigned. However I was trying to stay as close to OP's code as possible. But good point.
-13108 is simply 0xCCCC and that indeed indicates uninitialized memory access. You don't need to say (short)(0xcccccccc)
0

Several things:

  • Your arrays and pointers are declared as short, but scanf()/printf() specifiers are %d, which mean int. Typically short is a 16-bit integer, and int is a 32-bit integer. That can cause weird effects.
  • You should start your loops at 2 instead of 3. 3 is already outside bounds.
  • At the end of the final loop, all pointers will point beyond the ends of arrays, but you pass them to printf() anyway (which is actually undefined behavior).
  • As a matter of fact, don't you want to output the contents of C[] - the addition results? Why are you using punt_A and punt_B there?

Comments

0

Now this is rough fix for ur program

#include <stdio.h>
#include <iostream>

using namespace std;

unsigned i;

int main(){


/* Array`s inputs */

    int *A = new int[3];

    for( i = 3 ; i-- ; ){

        cout << "Insert number for [A]: " << endl;
        scanf("%d",&A[i]);
    }

    printf("\n");

    int* B = new int[3];

    for( i = 3; i-- ; ){

    cout << "Insert number for [B]: " << endl;
    scanf("%d",&B[i]);

    }

    int* C = new int[3];

// Pointers

    int *punt_A, *punt_B, *punt_C;

    punt_A = A;
    punt_B = B;
    punt_C = C;

// Addition

    for( i = 3; i--; ){

    *punt_C = *punt_A + *punt_B;
    punt_A++;
    punt_B++;
    punt_C++;

    }

    for(int i = 0; i < 3; i++)
    {
        cout << *C << endl;
        C++;
    }

delete [] A;
delete [] B;
delete [] C;
return 0;
}
  • In your program:

The problem was: You initialize an array of shorts. Size of short is 2 bytes. However, you are loading number, expecting integer %d wich is 4 bytes. So, you load in the 2 bytes, and the other two bytes just ommited. I compile it WITHOUT -Wall -pedantic flags and still get warning:

main.cpp: In function ‘int main()’:
main.cpp:17:21: warning: format ‘%d’ expects argument of type ‘int*’, but argument 2 has type ‘short int*’ [-Wformat=]
     scanf("%d",&A[i]);
                     ^
main.cpp:28:21: warning: format ‘%d’ expects argument of type ‘int*’, but argument 2 has type ‘short int*’ [-Wformat=]
     scanf("%d",&B[i]);

Now to fix this, make them all ints. But you asked for better solution. If you are given two arrays, and you have to sum them, and since you are using c++11, for you, it might be easier to use a container.

# include <stdio.h>
# include <iostream>

#include <vector>

#define COUNT 3

using namespace std;

unsigned i;

int main()
{
/* Array`s inputs */

    vector<int> A, B;

    int worker;

    for( i = COUNT ; i-- ; )
    {
        cout << "Insert number for [A]: " << endl;

        cin >> worker;
        A.push_back(worker);
    }

    for( i = COUNT ; i-- ; )
    {
        cout << "Insert number for [B]: " << endl;

        cin >> worker;
        B.push_back(worker);
    }

    for(int i = 0; i < COUNT; i++)
    {
        A[i] = A[i] + B[i];
    }
    cout << "summed up" << endl;

    for(vector<int>::iterator it = A.begin(); it != A.end(); it++)
    {
        cout << *it << endl;
    }
return 0;
}

Now notice, i made a define for your count. Moreover, I used aray A again for output, saving space. The problem is, that vector by itself has O(n) complexity for push_back() (unless you resrve the size, but that requires knowing exact number of inputs, wich might not be in future a case, you might load until EOF). To eliminate this and make the program faster, a list might be used for better performance.

But if you WANT to use pointers, use iterators. :]

(please notice that my code is not protected for fails, meaning that if you put in a letter, it will do strange thing, but i outlined the idea :]

1 Comment

Ye :] C++ is quite hard to learn :S Whenever you would need a help or need to explain something, you can write me (hope this has a possibility of private messages). There are lot of things in C++ and there is long path ahead of you. I burned myself coutless times in past :]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.