指针
指针是一个变量,存放内存单元的地址。
指针大小: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)的函数指针。