开发者

Basic help needed with pointers (double indirection)

I asked some time ago on an account I can'开发者_如何学Got remember how to manipulate basic pointers and someone gave me a really good demo

for example

char *ptr = "hello" (hello = a char array)

so now *ptr is pointing at 'h'

ptr++ means moving the ptr to point at the next element, to get its value I do *ptr and that gives me e


ok so far everything works as I hope :D, but now I need to manipulate a char **ptr and was wondering how I do this in a way that mimics the effects of a 2d array?

Some basic tips would be much appreciated as I need to do an assignment that has a **ptr to imitate a 2d array and without knowing how it does this first means I can't even solve it on paper (for example, how do you dereference a **ptr, how do you get [x][y] values etc)

thanks


You can subscript a pointer the same way you can subscript an array, provided all the addresses have been set up correctly.

Assuming the following declaration:

char **ptr;

here are the types of the various expressions:

       Expression        Type      Equivalent expressions (yield same value)     
       ----------        ----      -----------------------------------------
              ptr        char **   &ptr[0]
             *ptr        char *    ptr[0] 
         *(ptr+i)        char *    ptr[i]; &ptr[i][0]
            **ptr        char      ptr[0][0]
      *(*(ptr+i))        char      ptr[i][0]; *ptr[i]
    *(*(ptr+i)+j)        char      ptr[i][j]

thus:

  • ptr can be treated as though it was an array of strings (2-d array of char)
  • ptr[i] points to the beginning of the i'th string in the list
  • ptr[i][j] is the value of the j'th character of the i'th string in the list
  • The expressions ptr++ and ++ptr will advance ptr to point to the next string
  • The expressions (*ptr)++ and ++(*ptr) will advance *ptr to point to the next character

As for setting up your pointers, this arrangement assumes everything has already been allocated as static arrays or dynamically through malloc. You cannot just write

char **ptr = {"foo", "bar", "bletch"}; // using aggregate initializer on 
                                       // non-aggregate type; bad juju,
                                       // a.k.a undefined behavior

or

char **ptr;          // ptr has not been initialized to point anywhere 
ptr[0] = "foo";      // dereferencing ptr via subscript invokes undefined
ptr[1] = "bar";      // behavior
ptr[2] = "bletch";

Generally, when you're using a pointer as though it was an array, you'll use malloc or something similar to allocate your buffers:

char **ptr = malloc(sizeof *ptr * N);
if (ptr)
{
  ptr[0] = "foo";    // ptr[i] gets address of
  ptr[1] = "bar";    // string literal
  ptr[2] = "bletch";
  ...
}

or

char **ptr = malloc(sizeof *ptr * N);
if (ptr)
{
  size_t i;
  for (i = 0; i < N; i++)
  {
    ptr[i] = malloc(sizeof *ptr[i] * M); // strictly speaking, the sizeof
    if (ptr[i])                          // is not necessary here
    {
      //initialize ptr[i]
    }
  }
}


A pointer to a pointer is just that. For example:

// Declare our double-indirection pointer.
char** ptr;
// And initialize it:
char s1[] = "hello";
char s2[] = "world";
ptr = malloc(sizeof(char*) * 2);
ptr[0] = s1;
ptr[1] = s2;
// ptr now points to a pointer that points to 'h'.
char* ptr2 = *ptr;
// ptr2 points to 'h'.
char* ptr3 = *(ptr + 1);
// ptr3 points to "w".
char c = **ptr; // could be written as *(*ptr)
// c = 'h'.
char c2 = *(*(ptr + 1));
// c2 = 'w'.
char c3 = *(*(ptr) + 1);
// c3 = 'e'.


You may use them as you would a normal two-dimensional array. (Since effectively, that's what they are)

char** ptr = {"lorem", "ipsum", "dolor"};
char* s1 = ptr[0]; //Points to the beginning of "lorem"
char* s2 = ptr[1]; //Points to the beginning of "ipsum"
char c = ptr[2][4]; //Contains 'r'

This is due to the fact that:

int *a;
//...
int i = a[6];
int j = *(a + 6); //Same as previous line!

Cheers,

Amit Ron--

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜