How to print the values that are stored in the array using pointer and function in c

Hi. I am new to pointer I have done the following programme using pointer with array

#include<stdio.h>
void disp(int *);
void show(int a);

int main()
{
    int i;
    int marks[]={55,65,75,56,78,78,90};
    for(i=0;i<6;i++)
        disp(&marks[i]);
    return 0;
}
void disp(int *n)
{
    show((int) &n);
}
void show(int a)
{
    printf("%d",*(&a));
}

Open in new window


I am sending the address of n to the function show from the function disp and in the function show I want to print the values that is stored in the address n but in this program output is the address. What is wrong in the programme?
Sourodip KunduAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

ZoppoCommented:
Hi Sourodip Kundu,

sorry, I'm not sure if this could be homework, so I can't simply post the correct code here.

So I try to explain without making it too simple, I hope that's ok, if not or if you still have problems understanding it please tell..

1. There's one error in disp: you use the address-of operato (&) which returns the pointer to (i.o.w. address of) a variable (instance), but, first you already have a pointer, and second the function show expects a value or variable instead of a pointer.

To retrieve the value of a variable via a pointer you can use the indirection operator (*) - using this correctly even makes the (int) obsolete.


2. You hardcoded the values used in the for-loop, so the variable i iterates from 0 to 5, this means the loop runs 6 times, but you have 7 numbers in the array.

This is a common pitfall in C, when using hardcoded lengths/sizes these need to be carefully handled to keep related ones synchronized.

An easy way to do this is using a macro which (at compile time) can determine the number of elements in the array, i.e.:
#define SIZE_OF(x) ( sizeof(x) / sizeof( x[0] ) )

...
    for(i=0;i<SIZE_OF( marks );i++)
...

Open in new window

3. There's one other thing in show, it's not really an error but meaningless code: using the statement *(&a), where a is a variable, is the same as using the variable directly, because first &a returns the pointer to a, next the *(...) returns the value at the address that pointer points to, which again simply is the value of the variable a.


Hope this helps,

ZOPPO
1
Sourodip KunduAuthor Commented:
I am unable to understand your first point, please explain me with a simple example
0
ZoppoCommented:
ok, I'll try to explain better:

A variable is some kind of a placeholder for a value. A variable has two 'features', a type (i.e. int) and a value (which usually can be changed). A variable doen's take care (and in fact doesn't need to know) where its value is stored in memory. Such variables are often called 'instances' too because they representate one instantiated value of its defined type.

A pointer is nothing else then a variable, it's type in fact is number, which representates the place in memory, where a value of interest is stored. This number ist the 'address'.

One of the most important things to understand is that a pointer is even just a variable. Therefore it's even possible to declare a pointer-to-pointer, which is simply a pointer to a variable which is a pointer itself, a.s.o.

Using pointers instead of instances has some advantage, one of the most important advantages is that it makes it possible to pass variables by-reference to functions, which i.e. allows called functions to read/modify variabels which are instantiated and used in a caller function.

The address-of operator (&) is used to retrieve the address of a variable, or better said, it returns a pointer which points to the address of the instance.

The indirection- operator (*) is the opposite, used with a pointer it returns the value of the instance where the pointer points to.

So in shourt you can say: "Use & with a variable to get a pointer, use * with a pointer to get a value".

In you disp function you use &n, this returns the pointer to 'n', but the 'n' passed to disp already is a pointer 'int*', so what disp passes to show is a pointer to a value which itself is a pointer to a function which expects an instance.

Just a very simple example:void foo()
{
 int x = 42; // x is an instance, which gets the hardcoded value 42 assigned (iow. 'is initialized with 42')
 int y = 0; // just another instance initialized with 0
 int* p = &x; // p now points to the address where the value 42, which is associated to the variable 'x', is stored in memory
 y= *p; // retrieve the value where p points to and set it to y
 *p = 0; // set the value at the address where 'p' points to, thus change the value of the variable x
 // here x == 0 and y == 42.
}
So, in fact to fix the error in your disp-function it's enough to replace the '&' by a '*' in order to pass the value pointed to by 'x' to 'show' instead of a pointer to pointer as it's done now.

Hope this helps understanding the problem ...

Best regards,

ZOPPO
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Problems using Powershell and Active Directory?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

Sourodip KunduAuthor Commented:
Yeah I get it if I use the above code I have to use double pointer that is ** in the show function to retrieve the value that is stored in that address
0
ZoppoCommented:
Sorry, but this is not really a solution, because in fact it only works since two errors accidentally lead to correct result.

What you do is passing a pointer-to-pointer-to-int casted to int to the function show which expects an int. Then to retrieve the value to be printed you use multiple inderection operators to retrieve the value via the pointer-to-pointer passed.

This does work, but only in this situation, but it will fail doing some simple (and obviously expected) things like show( 5 ); - this will crash since trying to interpret '5' as a pointer always will generate an access violation or segment fault.

You should probably re-think the problem and try to break it down to the easiest cases.

I would suggest you first try to find the easiest implementation for a void show( int a ) function which is able to correctly prints 5 when you call show( 5 ); (just a hint: you won't need * or & at all for this). When you have this try to implement void disp( int* a ) in a way it works without doing any more changes in the show() function. In fact the only 'challange' in the disp() function is to retrieve an int value from the int* pointer, this is what the indirection operator is for.

ZOPPO
0
Sourodip KunduAuthor Commented:
I slightly changed my code and that is:-

#include<stdio.h>
void disp(int *);
void show(int **);

int main()
{
    int i;
    int marks[]={55,65,75,56,78,78,90};
    for(i=0;i<7;i++)
        disp(&marks[i]);
    return 0;
}
void disp(int *n)
{

    show(&n);

}
void show(int **b)
{

    printf("%d  ",**b);
}

Open in new window


This code works fine without error and without any warning.
0
ZoppoCommented:
Yes, this works and is error free, but since you had to change the 'show' function you can't use it for i.e. 'show(5);' anymore.

And it became unnecessary complicated.

But it's funny you're extremely near the needed solution, what you did in 'show' now is what you should have done in 'disp' (except using ** for pointer to pointer, one * would be enough).

Probably you just don't see it due to working too much on it, this can happen, so I give you the last hint which should make it abvious: in disp change the call show(&n); to show(*n); and change the function show to again be declared as void show(int b) {}
1
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.