![](https://img-blog.csdnimg.cn/fd4c20489ea84a02ae7be1afa5bec060.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5q2j5Zyo5Yqq5Yqb55qE5bCP5rKz,size_20,color_FFFFFF,t_70,g_se,x_16)
关于指针的一些出错点:
传过去的是首元素的地址,不是整个数组。
![](https://img-blog.csdnimg.cn/d39365e38fdd4d7d91bd5dc56397240c.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5q2j5Zyo5Yqq5Yqb55qE5bCP5rKz,size_17,color_FFFFFF,t_70,g_se,x_16)
可以用数组,也可以用指针来打印,指针会寻找最后一个‘\0’作为结束。
第一个解引用打印的是c.后面打印的是abcdef.
不能够修改,修改是错误的。有些编译器识别不到错误,比如vs.
容易见的错误:
解决常量字符串被修改的方法:加const。
int main()
{
char ch = 'w';
char *pc = &ch;
*pc = 'w';
return 0; }
还有一种使用方式如下:
代码 char* pstr = "hello bit."; 特别容易让同学以为是把字符串 hello bit 放到字符指针 pstr 里
了,但是/本质是把字符串 hello bit. 首字符的地址放到了pstr中。
int main()
{
char* pstr = "hello bit.";//这里是把一个字符串放到pstr指针变量里了吗?
printf("%s\n", pstr);
return 0; }
数组指针:本质上是指针。
先看一些概念
以上显示了一个数组存放了四个指针。
同样是一个数组放了四个指针,只不过放的是四个数组首元素的地址。
如果要打印如何打印:
parr[i]找到了这个数组的某个元素。相当于找到了某个指针,然后再通过这个指针打印出来5个元素。
通过以上就可以很清晰的了解数组指针。
做几个小小的练习,写一下数组指针:
数组指针如何打印呢?
指针解引用找到这个数组,然后利用数组的性质打印出来。
再对比一下普通数组的打印:
一个数组指针的使用:
#include <stdio.h>
void print_arr1(int arr[3][5], int row, int col) {
int i = 0;
for(i=0; i<row; i++)
{
for(j=0; j<col; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
void print_arr2(int (*arr)[5], int row, int col) {
int i = 0;
for(i=0; i<row; i++)
{
for(j=0; j<col; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
int main()
{
int arr[3][5] = {1,2,3,4,5,6,7,8,9,10};
print_arr1(arr, 3, 5);
//数组名arr,表示首元素的地址
//但是二维数组的首元素是二维数组的第一行
//所以这里传递的arr,其实相当于第一行的地址,是一维数组的地址
//可以数组指针来接收
print_arr2(arr, 3, 5);
return 0; }
如果用数组指针来打印如下,
打印的规则:先看一维数组。
不同形式的分分辩
![](https://img-blog.csdnimg.cn/8482a3860f274366af196ee21e121440.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5q2j5Zyo5Yqq5Yqb55qE5bCP5rKz,size_14,color_FFFFFF,t_70,g_se,x_16)
数组名是首元素的地址,首元素是一个int*类型的指针,存放它的变量用二级指针。
![](https://img-blog.csdnimg.cn/4a63dd0d12324feeb2c80bccdd8ead15.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5q2j5Zyo5Yqq5Yqb55qE5bCP5rKz,size_20,color_FFFFFF,t_70,g_se,x_16)
上面二维数组传参不能省略列。
数组名是首元素地址,一维数组的地址不能放在整型指针里面去,也不能放在二级指针里面,二级指针是用来存放一级指针变量的地址。只能用下面的第三个。
![](https://img-blog.csdnimg.cn/3743f5f2f6d74ca791ed0d58b4109139.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5q2j5Zyo5Yqq5Yqb55qE5bCP5rKz,size_10,color_FFFFFF,t_70,g_se,x_16)
函数指针:
函数指针的解引用:
利用函数指针建立一个计算器:
#include <stdio.h>
int add(int a, int b) {
return a + b; }
int sub(int a, int b) {
return a - b; }
int mul(int a, int b) {
return a*b; }
int div(int a, int b) {
return a / b; }
int main()
{
int x, y;
int input = 1;
int ret = 0;
do
{
printf( "*************************\n" );
printf( " 1:add 2:sub \n" );
printf( " 3:mul 4:div \n" );
printf( "*************************\n" );
printf( "请选择:" );
scanf( "%d", &input);
switch (input)
{
case 1:
printf( "输入操作数:" );
scanf( "%d %d", &x, &y);
ret = add(x, y);
printf( "ret = %d\n", ret);
break;
case 2:
printf( "输入操作数:" );
scanf( "%d %d", &x, &y);
ret = sub(x, y);
printf( "ret = %d\n", ret);
break;
case 3:
printf( "输入操作数:" );
scanf( "%d %d", &x, &y);
ret = mul(x, y);
printf( "ret = %d\n", ret);
break;
case 4:
printf( "输入操作数:" );
scanf( "%d %d", &x, &y);
ret = div(x, y);
printf( "ret = %d\n", ret);
break;
case 0:
printf("退出程序\n");
breark;
default:
printf( "选择错误\n" );
break;
}
} while (input);
return 0; }
函数指针来实现:
#include <stdio.h>
int add(int a, int b) {
return a + b;
}
int sub(int a, int b) {
return a - b; }
int mul(int a, int b) {
return a*b; }
int div(int a, int b) {
return a / b; }
int main()
{
int x, y;
int input = 1;
int ret = 0;
int(*p[5])(int x, int y) = { 0, add, sub, mul, div }; //转移表
while (input)
{
printf( "*************************\n" );
printf( " 1:add 2:sub \n" );
printf( " 3:mul 4:div \n" );
printf( "*************************\n" );
printf( "请选择:" );
scanf( "%d", &input);
if ((input <= 4 && input >= 1))
{
printf( "输入操作数:" );
scanf( "%d %d", &x, &y);
ret = (*p[input])(x, y);
}
else
printf( "输入有误\n" );
printf( "ret = %d\n", ret);
}
return 0; }
![](https://img-blog.csdnimg.cn/e65dfdd266764f32a4467ed566a9e721.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5q2j5Zyo5Yqq5Yqb55qE5bCP5rKz,size_19,color_FFFFFF,t_70,g_se,x_16)
回调函数:
建立一个排序函数:
关于void参数:
排序函数的使用:
-----------------------------------------------------------------------------------------------------------------------------
指针例题:
例题:
他们之间的类型不一样。编译器会有警告。
找到第二行解引用,相当于拿到第二行的数组名了。
打印的是at。