本人也是小白自学,不全或有误欢迎指出
目录
正文开始:
字符指针
一般为char*;下面我们看一个例子:
#include<stdio.h>
int main()
{
char arr[] = "abcder";
char* p = arr;
printf("%s\n", arr);//通过数组打印
printf("%s\n", p);//通过指针打印
return 0;
}
结果为:
abcder
abcder
--------------------------------
Process exited after 0.03702 seconds with return value 0
请按任意键继续. . .
可以看出,通过这两种方法打印得出的结果都是一样的。
下面我们来更深的理解一下,话不多说,举例子:
#include<stdio.h>
int main()
{
char* p = "abcdefj";//"abcdefj"是一个常量字符串
printf("%c\n", *p);
return 0;
}
我们都知道,指针只有四个字节,但是这里明显超过了四个,那么是不是会发生编译错误呢?
a
--------------------------------
Process exited after 0.03245 seconds with return value 0
请按任意键继续. . .
可以看到,打印出来的是它的首字母,也就是说这个指针储存的是它的首字母。如果把代码改一下,改成:
#include<stdio.h>
int main()
{
char* p = "abcdefj";//"abcdefj"是一个常量字符串
printf("%s\n", p);
return 0;
}
可以得到
abcdefj
所以字符串赋值给 *p 的不是所有的内容,而是首字母的地址。
同时 *p所指向的内容是不可以修改的,所以我们最好在指针前面加一个 const
如:
const char* p = "abcdefj";
可以防止其被修改,从而引起错误。
下面我们再来看一段代码:
#include<stdio.h>
{
char arr1[] = "abc";
char arr2[] = "abc";
char *p1 = "abc";
char *p2 = "abc";
return 0;
}
在这段代码里arr1[] != arr2[],而p1 == p2。这是由于两个字符串内容虽然相同,但是都要储存,所以位置不同,而指针为了节省空间,所以两个指针的位置是相同的。
指针数组
指针数组是数组,是用来存放指针的,话不多说,看例子:
#include<stdio.h>
{
char *p1[10];//存放字符指针的数组--- 指针数组
int *p2[10]; //存放整形指针的数组--- 指针数组
return 0;
}
所以有什么用呢?
例一:
#include<stdio.h>
int main()
{
int a = 10;
int b = 20;
int c = 30;
int *arr[3] = {&a, &b, &c};
int i = 0;
for(i = 0; i < 3; i++ )
{
printf("%d\n", *(arr[i]));
}
return 0;
}
例二:
#include<stdio.h>
int main()
{
int i,j;
int arr1[] = {1, 2, 3, 4};
int arr2[] = {2, 3, 4, 5};
int arr3[] = {3, 4, 5, 6};
int *parr[] = {arr1, arr2, arr3};
for(i=0; i<3; i++)
{
for(j=0; j<4; j++)
{
printf("%d ", *(parr[i]+j));
}
printf("\n");
}
return 0;
}
数组指针
数组指针是一个指针,看例子:
#include<stdio.h>
int main()
{
int *p = NULL;//p是整形指针--指向整形的指针---可以存整形的地址
char* pc = NULL;// p是字符指针--指向字符的指针---可以存字符的地址
int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int(*p)[10] = &arr//数组指针,指向数组的指针, 存数组的地址
return 0;
}
数组指针在二维数组以上的情况才更简单,这里有一个二维数组的知识点:
int arr[3][4] = {{1, 2, 3, 4}, {2, 3, 4, 5}, {3, 4, 5, 6}};
arr;//这里的数组名不是首元素地址,而是第一行的地址,也就是 {1, 2, 3, 4}的地址
下面来举一个简单的例子:
#include<stdio.h>
void test(int (*p)[4], int x, int y)
{
int i = 0;
int j = 0;
for(i = 0; i < x; i++)
{
for(j = 0;j < y ; j++)
{
printf("%d ",(*(*p+i)+j) );//*(*p+i)相当于arr[i] , *p+i相当于arr[i]的地址
}
printf("\n");
}
}
int main()
{
int arr[3][4] = {{1, 2, 3, 4}, {2, 3, 4, 5}, {3, 4, 5, 6}};
test(arr, 3, 4);
return 0;
}
可以得出结果为
1 2 3 4
2 3 4 5
3 4 5 6
--------------------------------
Process exited after 0.03375 seconds with return value 0
请按任意键继续. . .
(这里比较难理解,尽量多看几遍)
下面我们来巩固一下:
int arr[5];//是一个5元素的整形数组
int *arr1[10];//是一个数组,数组有十个元素,每个元素类型是int*,属于指针数组
int (*arr2)[10];//是一个指针,这个指针指向了一个十元素的数组,属于数组指针
int (*arr3[10])[5];//是一个指针,这个指针里有十个元素,每个元素都是数组指针
//每个元素都是指向一个五元素的数组,也属于数组指针
注:使用指针时要注意传参
函数指针
函数指针---指向函数的指针--存放函数地址的一个指针
且 &函数名 和 函数名 都是整个函数的地址。
二话不说举例子:
#include<stdio.h>
int sum(int x, int y)
{
return x+y;
}
int main()
{
int a = 0;
int b = 0;
int (*pa)(int, int) = sum;//这是求和的函数指针
printf("%d ", (*pa)(2, 3));
return 0;
}
可以猜到,它的结果为5
函数指针的模板:
void(*)();
看到这一类的代码,我们需要第一时间想到函数指针;
我们再返回刚才的求和的函数指针;
#include<stdio.h>
int sum(int x, int y)
{
return x+y;
}
int main()
{
int a = 0;
int b = 0;
int (*pa)(int, int) = sum;
printf("%d \n", (*pa)(2, 3));
printf("%d \n", (pa)(2, 3));
return 0;
}
结果为:
5
5
--------------------------------
Process exited after 0.03448 seconds with return value 0
请按任意键继续. . .
可以看到两种方法打印的结果是一样的,也就是说两种写法都OK的;
我们还可以通过函数指针的数组完成加减乘除,提示:
int(*ma[4])(int ,int) = {add, sud, mul ,div};
大家下去可以自己试试。。。。。
最后:
我是 @开卷&&有益 期待大家关注,一起进步。