指针部分较难的知识点
1.通过指针引用多维数组(本文中仅说明二维数组)
以int a[3][4]为例:
(1)a[0],a[1],a[2]均为一维数组名,则a[0]=&a[0][0] (C语言规定一维数组名代表数组首元素地址)
(2)a+1=(a+1)的值相同,(a+1)=a[1]. a+1虽然等于a[1],但是二者含义不同,a+1表示第1行的首址,而a[1]=a[1]+0表示a[1][0]的地址,因此对a+1与a[1]分别加1会得到不同的值
事实上,a[1]的类型为int* 型,而a+1为 int(*)[4]型
(3)int ( * a ) [4]与 int * a[4]的区别,很难理解
int a[3][4];
int (* p)[4]; (*和p先结合,表示*p(即p所指的)是一个维度为4的int型数组
p=a;
int * a[4]很好理解,a先与[4]结合表示一个4维数组,int *为数组类型,即一个4维指针数组。
(4)一维数组与二维数组在使用指向一维数组的指针进行遍历时,对初始化时的区别,很难理解
int a[3][4];
int (*p)[4];
p=a;
int a[4];
int (*p)[4];
p=&a;
对一维数组,虽然&a=a,但是,&a表示取整个数组第0行的地址,与a含义不同,可编程检验&a+1和a+1的值分别为多少
2.指向指针数据的指针。
例如: char * p; p之前有两个号,由于*运算符的结合性是从右往左的,所以 char * *p = char * (*p)。等式右边可以这样理解,*p表示p是一个指针 char *表示这个指针的数据类型是 char *型的,即指针p指向的数据是一个char型的指针
上代码😝:
#include <stdio.h>
int k=7;
void f(int **s)
{ int *t=&k;
*s=t;
printf("%d,%d,%d,", k, *t, **s);
}
main()
{ int i=3,*p=&i, **r = &p;
f(r); printf("%d,%d,%d\n", i, *p, **r);
}
运行结果:
[Running] cd "e:\C-programming-review\" && gcc project1.c -o project1 && "e:\C-programming-review\"project1
7,7,7,3,7,7
[Done] exited with code=6 in 0.524 seconds
分析:指针的指针。
本题各个变量的数据类型分别为:
i,k为整型变量,
p,t为整型指针,
r,s为指针,不过它们所指向的内容还是指针。
难理解:main函数中先让p指向i,即*p=i,再让r指向p,即 *r=p,**r= *p=i;再执行f(r),将r作为实参传给s,则 s=r, *s= *r=p,再让t指向k,即 *t=k,故此时 *s= *r=p=t,指针s所指向存储区域的内容变为t,又因为指针s和指针r指向同一片区域,故导致指针r所指向存储区域的内容变为t,又因为指针r所指向的区域为指针变量p的内容,故指针变量p的内容变为t,故在f函数调用结束后, **r= *p= *t=k=7.
本题可与上面的第3题对照着理解,
在下面的代码段2中,函数的参数是指针变量,而本题函数的参数是指针的指针,
并且,在代码段2中,并没有改变指针所指向的变量的值,改变的只是指针的值,故在函数调用完以后,函数外部作为实参的那个指针没有发生任何变化;而本题在所调用的函数中改变了指针所指向的变量的值,所以函数外部作为实参的指针和它所指向的变量的值都发生了变化。
作为对比,代码段2😝:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct stu {
char *name, gender;
int score;
} STU;
void f(char *p)
{
p=(char *)malloc(10);
strcpy(p, "Qian");
}
main()
{
STU a={NULL, 'm', 290}, b;
a.name=(char *)malloc(10);
strcpy( a.name, "Zhao" );
b = a;
f(b.name);
b.gender = 'f'; b.score = 350;
printf("%s,%c,%d,", a.name, a.gender, a.score);
printf("%s,%c,%d\n", b.name, b.gender, b.score);
}
本题考查指针作为函数的形参,在调用f函数时,b.name作为f函数的实参传递给形参p,但进入f函数的函数体之后,只是对指针p进行操作,并且f函数调用结束后,形参p指针的值不会回传给实参b. name。故b.name与a.name所指向区域的内容未发生变化
3.函数指针与指针函数:
函数指针的意思是某个指针所指向的内容是一个函数,而指针函数的意思是某个函数的返回值是一个指针。
例如:
int *f(int a, int b)
这是定义了一个指针函数,()运算符的优先级高于*运算符,故f会先于()结合,表示f是一个函数,int *表示这个函数的返回值是一个整型指针。故
int *f(int a, int b)= (int *) f(int a, int b)
int (*f)(int a, int b)
从左往右看,*f表示f是一个指针,它所指向的是一个函数😀
参考文献
《C程序设计》第四版 by 谭浩强


被折叠的 条评论
为什么被折叠?



