من الصعب التفكير في هذا ، لأن هناك مستويات متعددة من المؤشرات.
هنا مثال أبسط. هذا ما يمكن أن نسميه "المرور بالإشارة":
#include <stdio.h>
void f(int *ip)
{
*ip = 5;
}
int main(){
{
int i = 7;
printf("%d\n", i);
f(&i);
printf("%d\n", i);
}
وظيفة f
يقبل المؤشر إلى int. يعدل ذلك int. في main
، لدينا متغير int i
. نأخذ عنوان هذا المتغير باستخدام &
، وتمرير المؤشر الناتج للعمل f
. بهذه الطريقة ، تعمل f
قادر على التعديل i
في المتصل. لاحظ هذه الوظيفة f
يأخذ المؤشر إلى شيء ما ، وهذا ما يتطلبه المؤشر هو نوع i
في المتصل - بعبارة أخرى ، المؤشر إلى int.
الآن دعونا نلقي نظرة على مثال آخر. هذه المرة ، بدلا من التلاعب int
بالإشارة ، سنقوم بمعالجة متغير المؤشر ، أ char *
. (سننتهي في نهاية المطاف بالتعامل مع مؤشرات إلى مؤشرات.)
void g(char **sp)
{
*sp = malloc(10);
strcpy(*sp, "oranges");
}
int main(){
{
char *s = "apples";
printf("%s\n", s);
g(&s);
printf("%s\n", s);
}
مرة أخرى ، وظيفة g
يقبل حجة بالإشارة. مرة أخرى ، وظيفة g
قادر على تعديل متغير في المتصل الخاص به. مرة أخرى ، نوع المؤشر المقبول من قبل g
هو مؤشر للنوع الذي يتم التلاعب به. بما أن النوع الذي يتم التلاعب به هو "مؤشر إلى حرف" ، وظيفة g
يقبل المؤشر إلى المؤشر إلى حرف أو char **
.
لكن الشفرة التي نشرتها هي نوعًا ما مزيج من الاثنين. وظيفتك f
يقبل المؤشر int ، تمامًا مثل المنجم ، ويحاول استخدام هذا المؤشر لتعديل متغير int في المتصل. ولكن بعد ذلك ، في حياتك main
الوظيفة ، المتغير الذي تحاول تعديله ليس int ، إنه مؤشر إلى int ، أو int *
.
عندما تتصل
f(&p);
تبدأ بمؤشر إلى عدد صحيح ، p
، وأنت تأخذ عنوانها معه &
، مما أدى إلى مؤشر إلى مؤشر إلى int. ولكن بعد ذلك أنت ؛ إعادة استدعاء وظيفة f
، الذي يتوقع مؤشر إلى int. هذا ما يحاول المترجم إخبارك بالرسائل
warning: passing arg 1 of 'f' from incompatible pointer type
note: expected 'int *' but argument is of type 'int **'