This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

how cain pass through a pointer's address to a function

I declared different parameters, variables and pointers and I put into in two blocks. I declare and defined function for calculating, saving and checking chksum for both block.
I realised that the compiler give error message when I try to pass through the pointer's address to a function. I tried to use an another pointer to point to the pointer's address but the compiler didn't support it. Has anybody a good idea to solve my problem.
thank in advace
leslie



#include <reg51.h>
#define record 7
#define byte unsigned char
#define word unsigned int
#define dword unsigned long int
//declare funtions
void save_block(byte xdata *start_addr,word xdata *chksum);
word calc_block(byte xdata *start_addr,word xdata *chksum);
bit chk_block(byte xdata *start_addr,word xdata *chksum);
//declare variables
xdata byte par_buff1[14];
xdata word chksum1;
//
xdata byte dummy1;
//
xdata byte xdata *rec_buf_start;
xdata byte xdata *rec_buf_end;
xdata byte xdata *wr_ptr;
xdata byte xdata *rd_ptr;
xdata word chksum2;
//
xdata word xdata **valami;

main()
{
//valami=&rec_buf_start;
if(chk_block&rec_buf_start,&chksum2))
{
// do something
}
if (chk_block(&par_buff1[0],&chksum1))
{
//do something
}
else
{
//do something
}
for(;;)
{
//do something
}
}
//
// functions definition
//
bit chk_block(byte xdata *start_addr,word xdata *chksum)
{
if(*chksum!=calc_block(start_addr,chksum))
{
return 1; //setb c
}
else
{
return 0;
}
}
word calc_block(byte xdata *start_addr,word xdata *chksum)
{
xdata word blsumma;
while(start_addr!=(byte *)chksum)
{
blsumma+=(byte)*start_addr++;
}
return blsumma;
}
void save_block(byte xdata *start_addr,word xdata *chksum)
{
*chksum=calc_block(start_addr,chksum);
}

  • First, code is easier to read on this forum if you use the &ltpre&gt and &lt/pre&gt tags (see the "Tips for Posting Messages" link in the side bar) - like this:

    #include <reg51.h>
    
    #define record 7
    
    #define byte  unsigned char
    #define word  unsigned int
    #define dword unsigned long int
    
    //declare funtions
    void save_block( byte xdata *start_addr, word xdata *chksum );
    word calc_block( byte xdata *start_addr, word xdata *chksum );
    bit  chk_block(  byte xdata *start_addr, word xdata *chksum );
    
    //declare variables
    xdata byte par_buff1[14];
    xdata word chksum1;
    
    xdata byte dummy1;
    
    xdata byte xdata *rec_buf_start;
    xdata byte xdata *rec_buf_end;
    xdata byte xdata *wr_ptr;
    xdata byte xdata *rd_ptr;
    xdata word chksum2;
    
    xdata word xdata **valami;
    
    main()
    {
        //valami=&rec_buf_start;
        if(chk_block(&rec_buf_start,&chksum2))
        {
            // do something
        }
        if(chk_block(&par_buff1[0],&chksum1))
        {
            //do something
        }
        else
        {
            //do something
        }
        for(;;)
        {
            //do something 
        }
    } 
    etc
    

    OK, if I first fix the line
    if(chk_block&rec_buf_start,&chksum2))
    
    to
    if(chk_block( &rec_buf_start, &chksum2 ))
    
    I get just 1 compile error: "potiner to different objects"

    Look at the prototype of chk_block and the declaration of rec_buf_start:
    bit chk_block( byte xdata *start_addr, word xdata *chksum );
    xdata byte xdata *rec_buf_start;
    you see that rec_buf_start is already the pointer you want - no need to take its address!

    BTW: don't be afraid to put extra spaces in your code (eg, after commas) - it's easier to read!

    BTW2: typedef would be better than #define for your byte, word & dword
    (and I'd prefer names like U8, U16, U32, as "word" is ambiguous)

  • thanks for Your answer

    I understand your explanation, but I would like to a calculate pointers controlsum not that place where pointers point to. I can do it if I declare a new dummy byte(U8) variable before the line where my first pointer placed.

    //declare
    xdata byte dummy;
    xdata byte xdata *rec_buf_start;
    xdata byte xdata *rec_buf_end;
    xdata byte xdata *rd_ptr;
    xdata byte xdata *wr_ptr;
    xdata word chksum1;
    

    .. and I pass through the variable'address to function like this
    main()
     {
     *chksum1=calc_chk(&dummy, &chksum1);
     }
    
    I waste one byte and controlsum will involve dummy's value too.
    I can leave it if I write &dummy+1 into the calling precedure.
    It's not a big problem. Only I though that, there is other solution to pass through an pointer'address to a function.

  • You are not guaranteed to have these variables in order in memory (ANSI C). You can force this be selecting "Keep variables in order" I think but this is a weak thing to do. It's too fragile and will break easily. Put your pointers into a struct like this:

    typedef unsigned char  U8;
    typedef unsigned short U16;
    
    
    typedef struct {
        // All pointers to XDATA only.
        U8 * xdata rec_buf_start;
        U8 * xdata rec_buf_end;
        U8 * xdata rd_ptr;
        U8 * xdata wr_ptr;
    } Pointer;
    
    int main(void)
    {
        // Put struct into XDATA too.
        Pointer xdata ptrs;
        U16 idata chksum;
    
        chksum = calcChecksum(&ptrs);
    
        return 0;
    }
    But then again, maybe I don't understand what you are attempting to do.

    - Mark



  • So, you want to treat the pointers as just ordinary numbers, and calculate a checksum on those numbers?

    Can't you just use a cast?

  • Yes I'd like to do that, but I don't know how do I do it. I program always in assembly and nowadays i'd like to apply C language in my job. It's not to easy change my assembly oriented attitud.
    So I should greatly appreciate if You show it the good solution.

    thank in advance Leslie

  • unsigned char *Ptr;
    unsigned long  PtrVal;
    
        Ptr = &something;
        PtrVal = (unsigned long)Ptr;
    Ptr now contains the address of something; ie, it points to something.

    PtrVal now contains the numerical value of Ptr as an unsigned long

    eg, if the address of something is X:0x0019FE, the value of PtrVal will be 0x000119FE.

    (See the C51 manual for a description of how Keil implement pointers to cope with the 8051's different memory areas).