指向指针的指针等等......在C中 [英] Pointer to pointer to pointer and so on... in C

查看:75
本文介绍了指向指针的指针等等......在C中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可能存在指向指向指针指针的指针的指针......依此类推。

使用/处理它们会非常混乱。它有什么实际用处吗?

为什么我们需要将指针变量的地址存储到另一个指针变量等等?

请指教。 div class =h2_lin>解决方案

实际上有一种情况,指向指针非常方便。这是一个例子:让我们说你有一个链表,列表的锚点是这样的东西:

  struct  ListElement * pFirstElement; 



现在想象你想将该指针传递给一个函数,并让函数有机会修改pFirstElement的内容。然后你会传给指针指针:

  void  AddElement( struct  ListElement ** pAnchor, struct  ListElement * pElement)
{
...
}



在某些情况下,您需要指向指针的指针,但它们很少见。但是,看看,如果你设计一种编程语言并允许指针指针,那么这意味着你可以拥有任意深度的指针。事实上,在Paulo Zemek给出的例子中,您可以看到,指针深度可能会变得非常大 - 虽然没有人会在正常情况下使用它。



我希望回答了你的问题。


编程语言是一种工具,它赋予程序员权力,也有责任做有意义的事情。就像用锤子一样:它应该用来钉钉子,不要穿过玻璃窗。 ;-)



因此,C / C ++指针指向内存位置。存储器可以被视为一个大的连续字节数组,该存储器中的字节编号从0到存储器的末尾。该数字称为内存中字节的地址。



变量占用内存中的一个或多个连续字节以存储变量的值。变量的地址是变量的第一个字节的地址。



当你声明一个变量时,编译器会添加机制来访问该变量的内存位置。变量:如果为变量赋值,程序将确定变量的内存位置,并将值存储到该位置的字节。同样,当你从一个变量读取时:该内存位置的字节被解释为该变量的值(给定类型)。



这个地址机器是隐藏的给程序员。但在某些情况下,您需要变量的地址而不是变量的值。在这种情况下,您可以定义一个可以保存另一个变量地址的附加变量。这样的变量称为指针变量。例如。

  int  number =  5 ; 
int * pointerToNumber =& number;

* 告诉我我们不是存储 int ,而是存储该变量中 int 变量的地址。要访问变量的地址,请在选择的变量之前加上&



因为a指针变量也是一个变量,您可以再次获取该变量的地址等。



C中的用例:



交换两个变量的值:

- 你必须传递变量的地址。

- 如果变量是值直接传递,你无法在内存中交换它们。

  void  swap_int( int  * a, int  * b){ int  i = *一个; * a = * b; * b = i; } 
...
int a = 7 ;
int b = 13 ;
...
swap_int(& a,& b);
// 现在,a = 13,b = 7





在函数中设置指针变量(例如在工厂函数中):

  void  create_string( char  ** string, size_t  size)
{
* string =( char *)malloc(size);
...
}
...
char * s;
create_string(& s, 1000 );





多维数组:

  int  arrayNx1 [N];  //  在连续内存中存储N  int   
int arrayNxM [N] [M]; // 将N * int 存储在连续的内存中,
< span class =code-comment> // 每个指向单个块
// M int 在连续的内存中每个
int arrayUxVxW [U] [V] [W]; // arrayUxVxW是U ** int
的数组 // 每个arrayUxVxW [u]是一个V * int $的数组b $ b // 每个arrayUxVxW [u] [v]是一个W int 的数组
等。

你在这里看到你有能力做你需要的事情(例如多维阵列),但你有责任小心处理。初始化这样的多维数组留作练习;-)。



干杯

Andi



PS:并非所有变量都存储在内存中。可能的优化是仅将变量存储在CPU寄存器中。但这只有在您没有显式访问变量的地址时才有可能(CPU寄存器不在内存中,因此没有地址)。不过,这个优化留给了编译器。


你需要的只是知道指针是什么并使用你的大脑。如果您知道如何指向任何对象并通过指针访问它,您应该能够通过非常简单的推理找出该对象本身是指针时要做什么。这需要一些最小的练习。



PIEBALDconsult在评论中说:如果你不知道为什么,请远离C。不确定。我会说:如果你无法理解为什么只使用你的推理技巧,那就远离编程。



请不要误会我的意思:我不是坚持任何人都需要拥有C技能。我只说指针操作是所有开发人员应该掌握的基本操作。是的,有许多人在没有这些基本技能的情况下被正式视为开发人员,但谁认真对待他们?所以,这是最基本的障碍之一。你需要自己克服它,可能就是现在。除了C上的基本参考书之外,您不需要任何手册或教程。这并不像看起来那么难。



-SA

There could exist a pointer to a pointer to a pointer to a pointer to a pointer.. and so on.
It would be so confusing to use/handle them. Is there any practical use where it is really beneficial?
Why would we need to store a pointer variable's address into some another pointer variable and so on?
Please advise.

解决方案

There are in fact situations, where it is very handy to have a pointer to a pointer. Here is an example: Lets say you have a linked list and the anchor of the list is somethings like:

struct ListElement* pFirstElement;


Now imagine you want to pass that pointer to a function and give the function the chance to modify the contents of pFirstElement. Then you would pass a pointer to that pointer:

void AddElement (struct ListElement** pAnchor, struct ListElement* pElement)
{
   ...
}


And there are cases where you need a pointer to a pointer to a pointer, but they are rare. But see, if you design a programming language and allow pointers to pointers, then that implies that you can have pointers of arbitrary depths. In fact, in the example given by Paulo Zemek you can see, that the pointer depths can get quite large - although nobody would use that in normal circumstances.

I hope that answered your question.


A programming language is a tool that gives the programmer the power and also the responsibility to do meaningful things. Like with a hammer: it's supposed to drive nails, not to throw through glass windows. ;-)

So, C/C++ pointers are there to point to memory locations. The memory can be regarded as a large contiguous array of bytes, the bytes in that memory are numbered from 0 to the end of the memory. That number is called the address of a byte in memory.

A variable occupies one or more consecutive bytes in memory to store the variable's value. The address of the variable is the address of the first byte of the variable.

When you declare a variable, the compiler adds the machinery to access that memory location of the variable: if you assign a value to the variable, the program determines the memory location of the variable and stores the value to the bytes at that location. Likewise when you read from a variable: the bytes at that memory location are interpreted as the value of that variable (of a given type).

This address machinery is hidden to the programmer. But under certain conditions, you need the address of a variable instead of the value of the variable. In that case, you define an additional variable that can hold the address of another variable. Such a variable is called a pointer variable. E.g.

int number = 5;
int *pointerToNumber = &number;

The * tells that we are not storing an int but rather the address to an int variable in that variable. To access the address of a variable, you put a & before the variable of choice.

Since a pointer variable is also a variable, you can take the address of that variable again, etc.

Use cases in C:

Swapping the value of two variables:
- You must pass the address of the variables.
- If the variable's values were passed directly, you could not exchanged them in memory.

void swap_int(int *a, int *b) { int i = *a; *a = *b; *b = i; }
...
int a = 7;
int b = 13;
...
swap_int(&a, &b);
// now, a = 13, b = 7



Setting a pointer variable within a function (e.g. in a "factory" function):

void create_string(char **string, size_t size)
{
   *string = (char*)malloc(size);
   ...
}
...
char *s;
create_string(&s, 1000);



Multidimensional array:

int arrayNx1[N];         // store N int in consecutive memory
int arrayNxM[N][M];      // store N *int in consecutive memory,
                         // each pointing to individual chunks
                         // of M int in consecutive memory each
int arrayUxVxW[U][V][W]; // arrayUxVxW is an array to U **int
                         // each arrayUxVxW[u] is an array of V *int
                         // each arrayUxVxW[u][v] is an array of W int
etc.

You see here that you have the power to do the things you need (e.g. multi dimensional arrays), but you have the responsibility to handle with care. To initialize such multi dimensional arrays is left as exercise ;-).

Cheers
Andi

PS: Not all variables are stored in memory. A possible optimization is to store variables in CPU registers only. But this is only possible if you do not access the address of the variable explicitly (a CPU register is not located in memory and therefore has no address). This optimization is left to the compiler, though.


All you need is to know what a pointer is and using your brain. If you know how to point to any object and access it through pointer, you should be able to figure out what to do if that object is itself a pointer, by quite simple reasoning. It will take some minimal practice.

PIEBALDconsult said in his comment: "if you don't know why, stay away from C". Not sure. I would say: if you cannot figure why just using your reasoning skills, stay away from programming.

Please don't get me wrong: I'm not insisting that anyone needs to have C skills. I only say that the pointer operation is some basic thing which all the developers should master. Yes, there are many people formally considered as "developers" without these very basic skills, but who take them seriously? So, this is one of the first pretty basic barriers. You need to overcome it, all by yourself, probably right now. You don't need any manuals or tutorials except a basic reference book on C. This is not as hard as it may seem.

—SA


这篇关于指向指针的指针等等......在C中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆