/*二级指针——C语言*/
#include <stdio.h>
#include <string.h>
int main()
{
int a=10;
int *p=NULL;
int **q=NULL;
p=&a;
printf("a的地址:&a=%p\n",&a);
printf("p指向的地址:p=%p\n",p);
printf("p的地址:&p=%p\n",&p);
printf("p指向地址保存的内容:*p=%d\n",*p);
q=&p;
printf("q指向的地址:q=%p\n",q);
printf("q保存的内容:*q=%p\n",*q);
printf("q保存的内容为地址的内容:**q=%d\n",**q);
}
/*编译结果:
a的地址:&a=0xbfea5b90
p指向的地址:p=0xbfea5b90
p的地址:&p=0xbfea5b94
p指向地址保存的内容:*p=10
q指向的地址:q=0xbfea5b94
q保存的内容:*q=0xbfea5b90
q保存的内容为地址的内容:**q=10
*/
/*总结:**q为二级指针
p=&a;p为a的地址(&a),&p为p的地址,*p为a地址保存的内容(a)
q=&p;q为p的地址(&p),*q为p指向的地址(&a),**q为p指向地址的内容(a)
*/
/*指针数组*/
#include <stdio.h>
#include <string.h>
int main()
{
int i;
char *buff[]={"qwe","asd","zxc"};
for(i=0;i<3;i++)
{
printf("*buff[%d]=%s\n",i,*(buff+i));
}
}
/*编译结果:
*buff[0]=qwe
*buff[1]=asd
*buff[2]=zxc
*/
/*总结:
指针数组本质上是一个数组(指针类型的数组)
数组中的每一个元素的类型都是指针类型,使用的时候结合数组和指针规则使用。
*/
/*数组指针*/
#include <stdio.h>
#include <string.h>
int main()
{
int buff[2][3]={
1,2,3,
4,5,6
};
int (*p)[3]=buff;
printf("buff=%p\n",buff);
printf("p=%p\n",p);
printf("&p=%p\n\n",&p);
printf("buff[1][2]=%d\n",buff[1][2]);
printf("p[1][2]=%d\n\n",p[1][2]);
printf("*p[2]=%d\n",*p[1]);//第1行第0列,再计算*
printf("(*p)[2]=%d\n",(*p)[2]);
printf("(*(p+1))[2]=%d\n\n",(*(p+1))[2]);
int i,j;
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
printf("(*(p+%d))[%d]=%d ",i,j,(*(p+i))[j]);
printf("\n");
}
}
/*编译结果:
buff=0xbfc2d4f4
p=0xbfc2d4f4
&p=0xbfc2d4e8
buff[1][2]=6
p[1][2]=6
*p[2]=4
(*p)[2]=3
(*(p+1))[2]=6
(*(p+0))[0]=1 (*(p+0))[1]=2 (*(p+0))[2]=3
(*(p+1))[0]=4 (*(p+1))[1]=5 (*(p+1))[2]=6
*/
/*总结:
数组指针的本质是一个指针(数组类型的指针),数组指针常用于访问二维数组时使用。
使用“数据类型(*变量名)[数组长度]”的格式来定义一个数组指针。
例:int (*p)[3]:定义列长度为3的数组指针
数据类型:int (*)[3]
p的地址为数组首地址buff;
(*p)[j]为取第0行j列的元素;(*(p+i))[j]为取第i行j列的元素;*p[j]为取第j行0列的元素
*/
/*指针函数 char *fun() */
#include <stdio.h>
#include <string.h>
char *fun(char *buff,char *str)
{
char *head=buff;
while(*str!=0)
{
*buff++=*str++;
}
*buff=0;
return head;
}
int main()
{
char buff[128];
char str[]="QWER";
char *p=NULL;
p=fun(buff,str);
printf("buff[]=%s\n",buff);
printf("p[]=%s\n",p);
}
/*编译结果:
buff[]=QWER
p[]=QWER
*/
/*总结:
指针函数的本质上是一个函数(函数的类型是指针类型)
函数的返回值也是一个指针。
可参考文章/*指针在函数的应用*/
*/
/*函数指针 */
#include <stdio.h>
#include <stdlib.h>
void (*p)(int a,int b);
void fun(int a,int b)
{
printf("a+b=%d\n",a+b);
}
int main()
{
p = fun;
(*p)(10,20);
return 0;
}
/*编译结果:
a+b=30
*/
/*总结:
int (*p)(int,int); sizeof(p)=4
函数指针是指向函数的指针变量,函数指针本质上是指针。
在C语言中,每个函数都有一个入口地址,函数指针就是指向这个入口地址的变量。通过函数指针,我们可以调用函数,就像使用指针变量引用其他类型的变量一样。
函数指针的用法有以下几个方面:
(1)定义函数指针变量:可以使用函数返回类型 (*指针变量名)(参数列表)的语法来定义函数指针变量。例如,int (*p)(int, int)定义了一个指向返回类型为int,参数列表为两个int的函数的指针变量p。
(2)赋值函数指针变量:可以将一个函数的入口地址赋值给函数指针变量。例如,p = &add将add函数的入口地址赋值给函数指针变量p。
(3)调用函数指针变量:可以使用函数指针变量来调用函数。例如,int result = (*p)(a, b)通过函数指针变量p调用函数,传递参数a和b,并将返回值赋给result变量。
*/
/*空类型指针 void *p */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
void *v=NULL;
int buff[2]={10,20};
printf("要素(4)sizeof(v)=%d\n",sizeof(v));//所有地址所占字节为4
v=buff;
printf("sizeof(v)=%d\n",sizeof(v));
//printf("*v=%d\n",*v); //ERROR: 空类型指针 *v是非法取值,是一个非法间距寻址
printf("*(int *)v=%d\n",*(int *)v); /* 间接获取,先进行类型强制转换 */
int a;
int *p = &a;
*p = 21.5;
printf("要素(2)*p=%d\n",*p);
char *q=NULL;
q=(char *)malloc(sizeof(char)*10);
strcpy(q,"QWER");
printf("q=%s\n",q);
}
/*编译结果:
要素(4)sizeof(v)=4
sizeof(v)=4
*(int *)v=10
要素(2)*p=21
*/
/*总结:
空类型指针可以指向任何类型的元素的指针。
指针四要素 :
(1)指针必须有类型,指针类型是声明指向对象的类型。 int *p = NULL;
(2)指针所指向的数据类型,决定了指针值(指针指向对象地址里的数值)的数据类型。
(3)指针在使用时必须要有指向,如果没有指向,则指向为空,避免野指针出现。
(4)指针本身也占内存空间(指针本身也是一个变量)。
mallo函数分配成功返回所分配的内存空间的首地址(空类型内存空间)
*/