Thread: pointer using

  1. #1
    Registered User
    Join Date
    Mar 2008
    Location
    India
    Posts
    147

    pointer using

    My intention in this program is the function should display the given count of bytes from the given address pB, it should display 16 bits per line . each byte is displayed as 2 hex digits



    Code:
    #include<stdio.h>
    
    void dispBytes(unsigned char *pB,int count);
    
    
    void dispBytes(unsigned char *pB,int count)
    {
     char *temp;
    
    
     temp = pB;
    
     while(count > 0)
     {
                    printf("%x",*temp);
                    if (count % 16 == 0)
                    {
                            printf("\n");
                    }
                    temp++;
                    count--;
     }
    
     return ;
    
    }
    
    int main()
    {
    
            char cArr[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,32,33,34,35,36};
    
            dispBytes(cArr,20);
    
            return 0;
    }
    How can i make each bytes as 2 hex digits here..?

    Is my implementation correct in relation to my requirement ?

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Read up on printf format strings - subject for google.

    Also, 16 bits per line is 2 bytes - I expect you mean 16 bytes per line.

    Using count to count down and also to indicate if you have done 16 will work badly if you have a count that isn't a multiple of 16, say 25 - it will display 9 bytes first, then 16 bytes on the second line - probably not what you wanted. I'd suggest you use a separate loop variable for iterating the loop, and leave count unchanged in the code.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Technical Lead QuantumPete's Avatar
    Join Date
    Aug 2007
    Location
    London, UK
    Posts
    894
    I'd make a couple of small changes to your function:
    Code:
    void dispBytes(unsigned char *pB,int count)
    {
        char *temp = pB;
        short ii = 0;
    
        for (ii = 1; ii <= count; ii++, temp++)
        {
            printf("&#37;02x",*temp);
            if (ii % 16 == 0)
            {
                printf("\n");
            }
        }
        printf("\n");
    
        return ;
    
    }
    hth,

    QuantumPete
    "No-one else has reported this problem, you're either crazy or a liar" - Dogbert Technical Support
    "Have you tried turning it off and on again?" - The IT Crowd

  4. #4
    Registered User
    Join Date
    Jul 2008
    Posts
    133
    If temp is char*, then *temp will get ONE byte from memory, format won't help. 2 bytes need to be retreived at a time (or use short *temp).
    EDIT: and watch size/count carefully
    Last edited by rasta_freak; 08-13-2008 at 08:57 AM.

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by QuantumPete View Post
    I'd make a couple of small changes to your function:
    Code:
    void dispBytes(unsigned char *pB,int count)
    {
        char *temp = pB;
        short ii = 0;
    
        for (ii = 1; ii <= count; ii++, temp++)
        {
            printf("%02x",*temp);
            if (ii % 16 == 0)
            {
                printf("\n");
            }
        }
        printf("\n");
    
        return ;
    
    }
    hth,

    QuantumPete
    You change from unsigned to signed char - which will lead to "negative" chars being printed like this ffffff80 rather than 80.
    You use "short ii" - there is nothing indicating that count can only be small enough to fit in a short - is there a point to it?

    Otherwise, those were the type of changes I intended too.

    And pB could be "const unsigned char *", since the memory pointed to by pB is not changed, I just realized.

    I wonder how many times I've written a piece of code to dump some memory/data/file like that? Must be at least a dozen times (some in private projects, some "commercial" projects, etc).

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by rasta_freak View Post
    If temp is char*, then *temp will get ONE byte from memory, format won't help. 2 bytes need to be retreived at a time (or use short *temp).
    But the OP doesn't want to print two bytes at a time, he/she wants to print TWO digits at a time.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    Registered User
    Join Date
    Jul 2008
    Posts
    133
    Quote Originally Posted by matsp View Post
    But the OP doesn't want to print two bytes at a time, he/she wants to print TWO digits at a time.

    --
    Mats
    Ooopss, sorry to all. All that 16 bits,2 digits - got me confused....

  8. #8
    Registered User
    Join Date
    Mar 2008
    Location
    India
    Posts
    147

    Displaying the short data type in hexadecimal format using pointers

    Hello friends,

    My object here is to display the given count of 16 bit words from the given address pW, it should display 8 words perline and each word is displayed as 4 hex digit.

    Code:
    #include<stdio.h>
    
    
    void dispWords(unsigned short *pW,int count);
    
    
    void dispWords(unsigned short *pW,int count)
    {
            unsigned short *temp;
            int i;
    
            temp = pW;
    
            printf("\n Short \n");
            for(i=0;i<=count;i++)
            {
                     printf("%04x  ",*temp);
                     if(i!=0 && ( i % 8 == 0))
                     {
                             printf("\n");
                     }
                     temp++;
            }
    
            return;
    }
    
    
    int main()
    {
    
            char cArr[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,2 2,23,24,25,26,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53, 54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80 ,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,10 5,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,12 5,126,127};
    
             dispWords((short *)cArr,127);
     
            return 0;
    }
    Output is like below

    root@ahmed testprog]# ./ex6.o

    Short
    0100 0302 0504 0706 0908 0b0a 0d0c 0f0e 1110
    1312 1514 1716 1918 201a 2221 2423 2625
    2827 2a29 2c2b 2e2d 302f 3231 3433 3635
    3837 3a39 3c3b 3e3d 403f 4241 4443 4645
    4847 4a49 4c4b 4e4d 504f 5251 5453 5655
    5857 5a59 5c5b 5e5d 605f 6261 6463 6665
    6867 6a69 6c6b 6e6d 706f 7271 7473 7675
    7877 7a79 7c7b 7e7d 087f 0ff4 00bd 0000
    0000 3ca0 00aa 9768 bfe8 fe23 00ab 0001
    0000 9794 bfe8 979c bfe8 9be6 00a9 0ff4
    00bd 0000 0000 9720 bfe8 9768 bfe8 9710
    bfe8 fde5 00ab 0000 0000 0000 0000 0000
    0000 3fd4 00aa 0001 0000 82f8 0804 0000
    0000 9b20 00a9 a670 00a9 3fd4 00aa 0001
    0000 82f8 0804 0000 0000 8319 0804 8538
    0804 0001 0000 9794 bfe8 8590 0804


    My doubts are as below

    1) Is my solution correct ?

    2) why does it display 0302 0504 instead of 0203 0405 ..?

    3) In general i know that all the computer notation is in terms of binary , do we use hexadecimal notaion in real time . frankly to say iam bit confused with octal and hexadecmial notations.?

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    1) Is the solution correct?
    You are printing 8 items on all lines except the first and the last. That's probably not what you wanted.

    2) why does it display 0302 0504 instead of 0203 0405 ..?
    That has to do with "byte order", which is "how do we store a number that consists of multiple bytes". There are two types of byte ordering, "biggest first" (big endian) and "smallest first" (little endian). There isn't much of an advantage for one over the other, but in the past, there were some minor benefits of using one or the other in different circumstances. In this case, the "smallest first" appears to be the case, so your data comes out as 01 00 for the bytes 00 00, and 02 03 comes out as 0302.

    As you have probably realized, this only makes a difference if we deal with the data as bytes in one part, and then try to use the number as a bigger data type at some other point. There is one other time when it comes into effect, and that is when transferring data from one system to another, either by storing the data on a file and moving the media that the file is stored on (floppy, CD-ROM, Harddisk, Memory stick or some such) to another system. If the "new" system has a different byte order than the original one, the numbers will come out back-to-front. This ALSO happens when copying data across a network.

    3) In general i know that all the computer notation is in terms of binary , do we use hexadecimal notaion in real time . frankly to say i am bit confused with octal and hexadecmial notations.?

    Hexadecimal and octal are "practical ways to describe binary numbers". Our usual counting way, using base 10 does not translate well when converting to & from binary. Hexadecimal, using base 16, means that each group of digits is worth exactly 4 bits, so we can translate each hex digit to 4 bits quickly:
    Code:
    0 = 0000, 1 = 0001
    2 = 0010, 3 = 0011
    4 = 0100, 5 = 0101
    6 = 0110, 7 = 0111
    8 = 1000, 9 = 1001
    A = 1010, B = 1011
    C = 1100, D = 1101
    D = 1110, F = 1111
    The same applies for octal, which translates to groups of three bits, although it is rarely used these days. When I was at school, we had a PDP-11 machine there. The PDP-11 systems used octal quite a bit, particularly because the machine code instructions where based around groups of 3 bits (having 8 registers means that register numbers become 3 bits - 0..7)

    Code:
    0 = 000, 1 = 001
    2 = 010, 3 = 011
    4 = 100, 5 = 101
    6 = 110, 7 = 111
    If I give you the number 6234, and ask "is bit 9 set in that number" (the bit worth decimal 512), you would probably have to either use a calculator or pen and paper to come up with the answer. If we translate it to hex, it becomes 185A. Bit 9 is 0x200 in hex, so I can immediately say that bit 9 is not present in that number - if we SET bit 9 in that number, it becomes 1A5A.

    You may ask why we don't just use the binary representation directly. Well, mostly because binary numbers get very big very quickly. The 6234 number is already 13 bits long, and a 5 digit decimal number will be at least 14 bits long.

    So when the actual binary form of the number is the important bit, it becomes much easier to work with the number in hexadecimal form than it is to work with it in decimal form.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    Registered User
    Join Date
    Mar 2008
    Location
    India
    Posts
    147
    Thanks a lot for your detailed explanation.

    Here my first question is

    The solution expected to display 4 hex digit

    is my printf command correct i.e printf(" %04x",*temp);


    2) as for as little endian and big endian thing i understood that it will become a problem if transfer a data
    from one system to another system where one is a bigendian and another is little endian ( i.e least significan bit first)

    first of all how to know that other one is big endian / little endain.

    Once after we transfer the data do we have any provision to convert it to suit that environment.

    I did not understood this statement

    "As you have probably realized, this only makes a difference if we deal with the data as bytes in one part, and then try to use the number as a bigger data type at some other point."

    3) for third question i understood interms that it will become very easy if we use the hexdecimal notation bcz it represent more number of digits . i.e single digit = 4 bits

    Please correct me if iam wrong any where

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    %04x tells printf that you want: zero-filled (as opposed to blank), 4 characters width, in hex. So that is correct for printing a 16-bit number with all bits - 4 digits with 4 bits each makes a 16-bit word.

    My comment on the first question is rather that you are showing 9 groups of 4 digits on the first line, and 7 on the last line. You may want to adjust it so that you show 8 on each one (which is 16 bytes).

    Further, if you are showing the data as 16-bit words, but the count is given in bytes, then you probably shouldn't be showing as many lines as you are... [Sorry, didn't spot that last time].

    As to my answer to question 2:
    Note that BYTE ordering is different from BIT ordering. So "least siginficant bit first" is not the same as "least signficant byte first", necessarily [1]. But in a 16 bit word, we can store the least significant BYTE first or last, and that is what happens here (the least significant is first).

    When reading or storing BYTES, and then using those BYTES to form larger data, that is where you see the difference in byte order within a given system. As long as an int is an int (or a short a short), you really do not have to care which byte order they are. But if you were to store the data in an array of bytes, and then pass that to a function that makes a data into an integer, then you do need to KNOW which order the bytes are stored. Which is exactly what is happening in your example.


    [1] Also, regardless of which order the bytes are stored, the most significant bit of a short is bit 15, and the least significant is bit 0. So, when dealing with bits, byte order is also not important. Nor is it important if the physical location of bit 0 is to the left or the right (or up or down) - the LOGICAL location of bit 0 is always to the right, and bit 15 is 15 steps to the left of 0. So shifting something to the right will always produce a smaller number, and shifting to the left will produce a larger number [unless the digits fall of the edge, just like driving one mile after 99999 miles will make the odometer show 00000].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  12. #12
    Registered User
    Join Date
    Mar 2008
    Location
    India
    Posts
    147
    Thans mats

    The display is correct each word should be of 16 bits each and 8 words per line.

    I did some more changes in the program .Instead of static initilization of the array, i have dynamically
    created the array and initialized with the for loop. While displaying with the short version it gives a different result compare to the static initilized one. my code is as followed

    Code:
    #include<stdio.h>
    
    
    void dispWords(unsigned short *pW,int count);
    
    void dispWords(unsigned short *pW,int count)
    {
            unsigned short *temp;
            int i;
    
            temp = pW;
    
            printf("\n Short \n");
            for(i=0;i<=count;i++)
            {
                     printf("%04x  ",*temp);
                     if(i!=0 && ( i % 8 == 0))
                     {
                             printf("\n");
                     }
                     temp++;
            }
    
            return;
    }
    
    int main()
    {
            char *cArr;
            int i;
    
            cArr = malloc(sizeof(char) * 128);
    
            for (i=0;i<128;i++)
            {
                    cArr[i] = i;
            }
    
            dispWords((short *)cArr,127);
            return 0;
    }
    output

    100 0302 0504 0706 0908 0b0a 0d0c 0f0e 1110
    1312 1514 1716 1918 1b1a 1d1c 1f1e 2120
    2322 2524 2726 2928 2b2a 2d2c 2f2e 3130
    3332 3534 3736 3938 3b3a 3d3c 3f3e 4140
    4342 4544 4746 4948 4b4a 4d4c 4f4e 5150
    5352 5554 5756 5958 5b5a 5d5c 5f5e 6160
    6362 6564 6766 6968 6b6a 6d6c 6f6e 7170
    7372 7574 7776 7978 7b7a 7d7c 7f7e 0000
    0000 0f79 0002 0000 0000 0000 0000 0000
    0000 0000 0000 0000 0000 0000 0000 0000
    0000 0000 0000 0000 0000 0000 0000 0000
    0000 0000 0000 0000 0000 0000 0000 0000
    0000 0000 0000 0000 0000 0000 0000 0000
    0000 0000 0000 0000 0000 0000 0000 0000
    0000 0000 0000 0000 0000 0000 0000 0000
    0000 0000 0000 0000 0000 0000 0000

    where as for the static one output is

    0100 0302 0504 0706 0908 0b0a 0d0c 0f0e 1110
    1312 1514 1716 1918 1b1a 1d1c 1f1e 2120
    2322 2524 2726 2928 2b2a 2d2c 2f2e 3130
    3332 3534 3736 3938 3b3a 3d3c 3f3e 4140
    4342 4544 4746 4948 4b4a 4d4c 4f4e 5150
    5352 5554 5756 5958 5b5a 5d5c 5f5e 6160
    6362 6564 6766 6968 6b6a 6d6c 6f6e 7170
    7372 7574 7776 7978 7b7a 7d7c 7f7e 0000
    0000 3ca0 00aa f118 bfe7 fe23 00ab 0001
    0000 f144 bfe7 f14c bfe7 9be6 00a9 0ff4
    00bd 0000 0000 f0d0 bfe7 f118 bfe7 f0c0
    bfe7 fde5 00ab 0000 0000 0000 0000 0000
    0000 3fd4 00aa 0001 0000 82f8 0804 0000
    0000 9b20 00a9 a670 00a9 3fd4 00aa 0001
    0000 82f8 0804 0000 0000 8319 0804 8538
    0804 0001 0000 f144 bfe7 8590 0804

    can you please explain me why the differnce is like this.

    Any error while initilizing the array ,

    But the simple byte by byte dispaly works well i.e printf("%02x",*temp) works here i am sending array as char.

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    You are outputting 256 bytes (16 rows * 8 numbers * 2 bytes = 256) out of a buffer that contains 128 bytes. The remaining 128 bytes contain whatever happens to be after the 128 bytes you have defined - which is undefined. It appears that malloc'd memory, at least in this case, contains zero.

    I did try to say that earilier:
    Further, if you are showing the data as 16-bit words, but the count is given in bytes, then you probably shouldn't be showing as many lines as you are... [Sorry, didn't spot that last time].
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  14. #14
    Registered User
    Join Date
    Mar 2008
    Location
    India
    Posts
    147
    thanks a lot mats

    i did not realized that in my previous attempt.

  15. #15
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    Just a side note, any reason why you're running this as root!?!

    I hope you don't "use" root as a normal "account".

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Following CTools
    By EstateMatt in forum C Programming
    Replies: 5
    Last Post: 06-26-2008, 10:10 AM
  2. Quick Pointer Question
    By gwarf420 in forum C Programming
    Replies: 15
    Last Post: 06-01-2008, 03:47 PM
  3. Parameter passing with pointer to pointer
    By notsure in forum C++ Programming
    Replies: 15
    Last Post: 08-12-2006, 07:12 AM
  4. Direct3D problem
    By cboard_member in forum Game Programming
    Replies: 10
    Last Post: 04-09-2006, 03:36 AM
  5. Struct *** initialization
    By Saravanan in forum C Programming
    Replies: 20
    Last Post: 10-09-2003, 12:04 PM