指针数组与数组指针
指针数组和数组指针
(1)指针数组的实质是一个数组,这个数组中存储的内容全部都是指针变量
(2)数组指针的实质是一个指针,这个指针指向的是一个数组
分析指针数组与数组指针的表达式
(1)int *p[5]; int (*p)[5]; int (p[5])
(2)我们在定义一个符号是,关键在于:首先要搞清楚你定义的符号是谁(第一步:找核心);其次再来看谁跟核心最近,谁跟核心结合(第二步:找结合);以后继续向外扩展(第三步:继续向外结合直到整个符号完)
(3)如果核心和结合,表示核心是指针;如果核心和[ ]结合,表示核心是数组;如果核心和()结合,表示核心是函数
函数指针与typedef
(1)函数指针的实质还是指针,还是指针变量,本身占4个字节,
(2)函数指针其实就是一个普通变量,这个普通变量的类型是函数指针变量类型,它的值就是某个函数的地址(也就是它的函数名这个符号在编译器中对应的值)
函数指针的书写和分析方法
(1)C语言本身是强类型语言(每一个变量都有自己的变量类型),编译器可以帮我们做严格的类型格式检查
(2)假设我们有个函数是:void func(void);对应的函数指针:void (p)(void);类型是:void ()(void)
(3)函数名和数组名最大的区别就是:函数名做右值时不加&效果和意义都是一样的;但是数组名做右值时加不加&意义就不一样
void func1(void)
{
printf("test for function pointer.\n");
}
int main(void)
{
void (*pFunc)(void);
pFunc = func1; //左边是一个函数指针变量,右边是一个函数名
pFunc = &func1; //取函数的地址一样的
pFunc(); //用函数指针来解引用以调用该函数
}
typedef关键字的用法
(1)C语言中的类型一共有两种:一种是编译器定义的原生类型,第二种是用户自己定义的类型
(2)typedef是C语言中一个关键字,作用是用来定义类型重命名的,也就是说typedef加工出来的是类型,而不是变量
typedef char * (*pType)(char *,const char *)
int main()
{
typedef p2;
p2 = p3;//野指针,只是用来验证
}
函数指针实战
函数指针调用执行函数
(1):当程序出现段错误,第一步定位段错误,定位的方法就是在可疑处加打印信息,从而锁定导致段错误的语句,然后集中分析这句为什么会段错误
(2):linux中命令行默认是行缓冲,意思是当我们程序printf输出的时候,linux不会一个字一个字的输出我们的内容,而是将其缓冲起来放在缓冲区的等一行准备完了再一次把一行全部输出出来(为了效率。)linux判断一行有没有完的依据就是换行符’\n’(windows中换行符\n\r,linux中是\n,)
(3)关于linux命令行下用scanf交互性代码的问题,一下几点:
1、命令行下的交互程序纯粹是用来学习编程用的,几乎没有实践意义
2、scanf是和系统的标准输入打交道,printf和标准输出打交道。要搞清楚需要把标准输入输出搞清楚
3,我们用户输入内容时结尾都会以\n结尾,但是程序中scanf的时候都不会去接收最后的\n,导致这个回车还存在标准输入中,下次在scanf时都会被拿出来,所以导致错误
#include <stdio.h>
typedef int (*Func)(int , int);
int add(int a,int b);
int sub(int a,int b);
int multiple(int a,int b);
int divide(int a,int b);
int main(void)
{
Func p1 = NULL;
char c = 0;
int a = 0, b = 0, result = 0;
printf("请输入你需要运算的两个数字\n");
scanf("%d %d",&a,&b);
printf("请输入你需要运算的符号\n");
do
{
scanf("%c",&c);
}while(c == '\n'