指针详解

指针

指针是一个变量,存放内存单元的地址。

指针大小:32位平台上是4个字节,64位平台上是8个字节。

1.一级指针:存放内存的地址。
#include <stdio.h>
int main()
{
	int a = 10;
	int*p = &a;//将a变量的地址,存放在指针里,*p即是一级指针,int是*p所指向的内容是int类型。
	*p = 20;//通过*p可以改变a的值。
	printf("%d\n",a);//a=20.
	return 0;
}
2.二级指针

存放的是一级指针的地址。

#include <stdio.h>
int main()
{
	int a = 10;
	int*p = &a;
	int**pa = &p;//将p的地址存放在指针里,*pa是一个指针。int*是*pa所指向的内容是int*类型
	**pa = 20;//通过二级指针可以改变a的值。
	printf("%d\n",a);
	return 0;
}
3.指针和数组

数组名是数组首元素的地址。

int main()
{
	int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	int *p = &arr;将数组的地址传到指针里面
	printf("%p\n",p);//指针的地址
	printf("%p\n",arr);整个数组的地址
	printf("%p\n",&arr[0]);//数组首元素的地址
	//这三个结果一样.
	return 0;
}

通过指针的解引用可以找到数组里面每个元素。
即arr[i]=*(p+i).

int main()
{
	int arr[] = {1,2,3,4,5,6,7,8,9};
	int* p = &arr;
	int sz = sizeof(arr) / sizeof(arr[0]);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d\n", arr[i]);//访问数组里面每个元素。
		printf("%d\n", *(p + i));//通过指针访问数组里面每个元素。
		//两个效果一样
	}
	return 0;
}

4.指针数组

指针数组首先是一个数组,这个数组里面每个元素都是一个指针。

int*arr[5]:arr就是一个指针数组,这个数组有5个元素,每一个元素都是整型指针,指针所指向的内容是int类型的。

5.字符指针

两种情况

int main()
{
	char ch = 'w';
	char *p = &ch;//将一个字符的地址存放在指针里
	*p = 'x';//通过指针改变ch的值
	printf("%c\n",ch);//ch = x
	return 0;
}
int main()
{
	char* ch = "senpaolove";//将字符串首元素的地址存放在ch里.
	printf("%s\n",ch);
	return 0;
}
6.数组指针

数组指针首先是一个指针,这个指针指向的是一个数组。

int(*p)[5]:p是一个数组指针,这个指针指向一个数组,这个数组有5个元素,每个元素都是int类型。 这个数组指针的类型是int(*)[5].

void Print(int(*arr)[3], int row,int col)//这个指针指向的是一个数组,这个数组有3个元素,每个元素是int类型。
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		for (j = 0; j < col; j++)
		{
			printf("%d ",arr[i][j]);
		}
		printf("\n");
	}
}
int main()
{
	int arr[3][3] = {1,2,3,4,5,6,7,8,9};
	Print(arr, 3,3);
	//arr是数组名,表示首元素的地址,但是这个二维数组首元素是一个一维数组,所以可以用一个指针数组接收
	return 0;
}
7.函数指针

首先是一个指针,存放的是一个函数的地址。

int(*p)(int ,int) p是一个函数指针,这个指针指向的是一个函数,这个函数有两个参数,分别为int,int类型,这个函数的返回值也是int。函数指针类型为int(*)(int,int).

int Add(int a, int b)
{
	return a + b;
}
int main()
{
	int a = 10;
	int b = 20;
	int ret = Add(a, b);
	int(*p)(int,int) = &Add;//p是一个函数指针,指向的就是Add函数。
	printf("%d\n",*p);
	return 0;
}
(*(void (*)())0)();  void(*)()是一个函数指针,这个指针指向了一个无参,返回值为void的函数;
                    (void(*)())0这是将数字0强制类型转换成为函数指针;
                    *((void(*)())0)是解引用操作,将0地址处所表示的函数解引用;
                    所以这整体是一个函数,这个函数无参,无返回。
void (*signal(int , void(*)(int)))(int);  首先signal是一个函数声明,有两个参数,一个为int,另一个是一个函数指针,(这个指针指向了参数为int,返回值为void的函数);
                                          signal(int , void(*)(int))是一个函数指针,这个指针指向的是参数为int,返回值为void的函数。
                                          不过一般不这么写
                                          typedef void(*p)(int)
                                          然后代码就可以写成 p signal(int,p).
8.函数指针数组

首先是一个数组,这个数组里面存放的元素都是函数指针。

int(*p[5])():是一个数组,数组有5个元素,每个元素是int(*)()的函数指针.

int(*p[5])(int x, int y) = { 0, add, sub, mul, div };
这是一个函数指针数组,数组里存放的都是int(*)(int x,int y)的函数指针。
9.指向函数指针数组的指针

首先是一个指针,指向的是一个数组,这个数组里面存放的都是函数指针。
int (*(*p)[5])(int,int) :p是一个指针,这个指针指向了一个数组,数组里有5个元素,每个元素是int(*)(int,int)的函数指针。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值