`C语言之指针(下) -----Day15`
一.知识点回顾和补漏
1.数组与指针之间的表达关系
int a[2][3] = {1,2,3,4,5,6};
int (*p)[3];
a:表示二维数组名,指向一维数组a[0],即0行的首地址,是行指针
a[i] == *(a+i):表示第i个元素的地址
a+1 == &a[1]:表示第一行的首地址
a[1] == *(a+1) : 表示第一行第0列的首地址
a[i]+1 == *(a+i) +1 = = &a[i][1] :表示第i行第1列的元素的地址
*(a[i]+1) == *( *(a+i) + 1) = = a[i][2] :表示第i行第2列元素的值
2.指针的总结
3. 字符串与指针
- Char *p = “hello”;
指针变量p只存放字符串的首地址,与字符串的内容没有多大关系
*p = “world”; 是错误的表达方式,*p是常量不能修改
但是指针变量的值是可以改变的
二.知识点整理
1. void型指针类型
表示指针变量p不指向一个确定的类型数据,可以用任何类型的指针直接给void指针赋值,但是如果需要将void指针的值赋给其他类型的指针,则需要进行强制类型转换
2. 指向函数的指针
- 定义方式
int fun(int *a, char *b, float *c){} //函数主体
int main(){
int *p(int*,char*,float*) = fun; // 定义函数
int x = fun(a,b,c); //调用
}
int *fun(void *a. int **b)
{
}
int sum(int a,int b)
{
Return a+b;
}
int dev(int a,int b)
{
Return a-b;
}
int main()
{
int (*pfun)(int,int) = sum;
printf(%d“,sum(1,2));
printf(%d“,pfun(1,2));
printf(%d“,*sum(1,2));//是错误的 printf(%d“,(*sum)(1,2));//是正确的
printf(%d“,(*pfun)(1,2));
Return 0;
Int(*ffun)(void *,int **) = fun;
Int *(*pfun)(void *,int **) = fun;
Int *(*p[5])(void *,int **);
int (*p[4][5]);
3. 带返回值的函数
- 定义方法 类型名 *函数名(参数列表)
int *fun(int x, int y);
4.指针数组作main函数的形参
void main(int argc,char *argv[ ])
注意:1.main函数里面的参数名可以改变,但是参数个数没有办法改变,只能通过命令行的模式将参数传入进去
5. 空指针和NULL值的关系
Char *p ; // 这样的表述方法不正确
p = NULL; 地址也是非法的不能访问;把不用的指针都置为NULL,只是为防止乱指
NULL:一般表示控制,相当于0
6. 回调函数
- 回调函数的列子
#include<stdlib.h>
void fun(void)
{
Printf(“hello world”);
}
int main()
{
atexit(fun);//当程序快要结束的时候,调用fun函数,可以用做清理工作(吧配置文件)
printf(“13246\n”);
return 0;
}
三.疑难点整理
1.定义了一个一级指针p,若要在函数里面改变p的指向如何进行操作?
在进行实参向形参传递的过程中,将实参设置为int *p; 而形参改为二级地址**p,就可以进行修改
2.const指令的介绍
const在左边是只读指针,可以指向有效地址,可以指来指去,无法通过该指针去修改;
const在右边为常量指针,需要初始化,指向后无法在指向其他地方,但是可以通过指针变量修改内存
const int a = 10; a始终为10,不能改变;
char *p//可以通过p去访问(读取和修改内存)
const char *p;
char const *p;
char *const p;
const char * const p;//只读常量指针,不能指来指去,也无法通过该指针去修改内存
char const * const p;
四.自我总结
今天的学习,是将指针的指数点基本上全部学完了,学完之后我对函数与指针的操作、二维数组与指针的操作还有很多的知识点混淆,还需要不断的思考和感悟,一点一点将这些知识点消化到我的脑子里。