当前位置: 首页 > wzjs >正文

中国十大电商平台排行榜宁波网站推广优化公司怎么样

中国十大电商平台排行榜,宁波网站推广优化公司怎么样,电子商务平台怎么赚钱,营销网络搭建在经过前面两篇指针知识博客学习之后,我相信你已经对指针有了一定的理解,今天将更新C语言指针最后一篇,一起来学习吧。 1.字符指针变量 在指针类型的学习中,我们知道有一种指针类型为字符指针char*,之前我们是这样使用…

在经过前面两篇指针知识博客学习之后,我相信你已经对指针有了一定的理解,今天将更新C语言指针最后一篇,一起来学习吧。


1.字符指针变量

在指针类型的学习中,我们知道有一种指针类型为字符指针char*,之前我们是这样使用的:

int main()
{char ch = 'o';char* pc = &ch;*pc = 's';return 0;
}

 其实他还有一种使用方法:

int main()
{char* pstr = "hello world";printf("%s\n", pstr);return 0;
}

观察结果,我们是不是认为将字符串"hello world"存入了字符指针pstr里了,其实并不是,第三行本质上是将"hello world"首字符的地址放到了pstr中。

上⾯代码的意思是把⼀个常量字符串的首字符 h 的地址存放到指针变量 pstr 中。 

我们来看一道笔试题:

int main()
{char str1[] = "hello bit.";char str2[] = "hello bit.";const char* str3 = "hello bit.";const char* str4 = "hello bit.";if (str1 == str2)printf("str1 and str2 are same\n");elseprintf("str1 and str2 are not same\n");if (str3 == str4)printf("str3 and str4 are same\n");elseprintf("str3 and str4 are not same\n");return 0;
}

结果为: 

这⾥str3和str4指向的是⼀个同一个常量字符串。 C/C++会把常量字符串存储到单独的⼀个内存区域,当几个指针指向同⼀个字符串的时候,他们实际会指向同⼀块内存。但是用相同的常量字符串去初始化不同的数组的时候就会开辟出不同的内存块。 所以str1和str2不同,str3和str4相同。

 2.数组指针变量

上篇博客中我们学习了指针数组,指针数组是一种数组,数组中存放的是地址。

那么数组指针又是指针还是数组呢?

在之前的学习中,我们学习了整型指针变量和字符型指针变量,它们都是指针,由此类推,数组指针应该是:存放数组的地址,能够指向数组的指针变量。

我们先来看一个简单的数组指针变量:

int (*p)[10];

 p先与*组合,说明p是一个指针变量,指向的是一个大小为10个整型的数组。

注意:[ ]的优先级要高于*,所以必须加上( )来保证p与*结合,如果没有( ),就变成了int*   p[10],这是一个指针数组,该数组里可以存放10个整形指针变量。

 了解了数组指针,那么该怎么初始化呢?

经过之前的学习,我们知道&arr表示的是整个数组的地址,所以我们可以这样初始化:

 可以看到,&arr和p的类型是完全一致的。

数组指针类型分析:

int (*p) [10] = &arr;

|       |      |
|       |      |
|       |   p 指向数组的元素个数
|     p 是数组指针变量名
p 指向的数组的元素类型


3.二维数组传参的本质

根据数组名就是数组首元素地址这个规则,二维数组的数组名表示的应该就是第一行的地址,是一维数组的地址,如图,第一行的一维数组类型是 int[5],所以第一行的地址类型是 int (*p)[5]。

看下面代码:

void test(int (*p)[5], int r, int c)
{for (int i = 0; i < r; i++){for (int j = 0; j < c; j++){printf("%d ", *(*(p + i) + j));}printf("\n");}
}int main()
{int arr[3][5] = { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7} };test(arr, 3, 5);return 0;
}

 ⼆维数组传参,形参的部分可以写成数组,也可以写成指针形式。


4.函数指针变量

4.1函数指针变量的创建与使用

什么是函数指针变量?

通过前面整型变量,数组指针变量的类比,我们不难看出函数指针变量也是一种指针变量。函数指针变量是用来存放函数地址的,通过地址可以调用函数,有些人可能这时候就要问了,函数还有地址吗?我们来做个测试验证一下:
 

可以看到,我们成功打印出了地址,说明函数就是有地址的,函数名就是函数的地址,当然也可以通过&函数名的方法获取函数地址。

函数指针变量就是将函数的地址存放起来,他与数组指针变量类似,如下:

void test()
{int i = 0;
}void (*pf1)() = test;
//void (*pf1)() = &test;int Add(int x, int y)
{return x + y;
}int (*pf2)(int, int) = Add;
//int (*pf2)(int, int) = &Add;

函数指针变量类型分析:

int                (*pf3)               ( int x, int y)
|                      |                     ------------
|                      |                            |
|                      |         pf3 指向函数的参数类型和个数的交代
|           函数指针变量名
pf3 指向函数的返回类型
int   ( * )  ( int x, int y) //pf3 函数指针变量的类型

学会了就要马上应用起来,我们来看一个代码:

int Add(int x, int y)
{return x + y;
}int main()
{int (*pf)(int, int) = Add;printf("%d\n", (*pf)(3, 5));printf("%d\n", (*pf)(3, 10));return 0;
}

这是一段很简单的示例,大家自己要多多尝试。

 4.2两段有趣的代码

1   ( * ( void (*) ( ) ) ) ( );

2   void (*signal ( int , void  (*) (int) ) ) (int);

这两段代码一开始看可能会出现看不明白的情况,我们要学会将它们拆分。

首先,我们来看第一段代码:
1.void (*) ( ):这是一个函数指针类型,表明该指针指向的函数没有参数,并且返回值为void

2.void (*) ( ) ) ):把整数0强制转换为void (*) ( )类型的函数指针,意味着让这个指针指向内存地址0

3.* ( void (*) ( ) ) 0:对这个函数指针进行解引用操作,从而得到函数本身。

4.( * ( void (*) ( ) ) ) ( ):调用解引用后得到的函数,也就是调用位于内存地址0处的函数。

第二段代码:

 1.void  (*) (int):这是一个函数指针类型,表明该指针指向的函数中有一个参数,类型为int,并且返回值为void

2.signal ( int , void  (*) (int) ):这是一个函数,该函数有两个参数,一个参数类型为int,另一个参数类型是一个函数指针

3.void (*signal ( int , void  (*) (int) ) ) (int):signal 函数返回一个函数指针,这个返回的函数指针类型也是 void (*)(int)

4.3typedef关键字 

typedef 是⽤来类型重命名的,可以将复杂的类型,简单化。
比如,你觉得 unsigned int写起来不方便,如果能写成 uint 就方便多了,那么我们可以使⽤:
typedef unsigned int unit;
//将unsigned int 重命名为unit
如果是指针类型,能否重命名呢?其实也是可以的,⽐如,将 int* 重命名为 ptr_t ,这样写:
typedef int* ptr_t;
但是对于数组指针和函数指针稍微有点区别:
比如我们有数组指针类型 int(*)[5] ,需要重命名为 parr_t ,那可以这样写:
typedef int(*parr_t)[5];//新类型名必须在*的右边
函数指针类型的重命名也是⼀样的,⽐如,将 void(*)(int) 类型重命名为 pf_t ,就可以这样写:
typedef void(*pun_t)(int);

我们在重新来看这个代码:

void (*signal ( int , void  (*) (int) ) ) (int);
typedef void(*prse)(int);
prse signal(int,prse);

是不是要简单很多了,函数名为signal,有两个参数,一个是int,一个是prse,返回值也是prse。

5.函数指针数组

数组是⼀个存放相同类型数据的存储空间,我们已经学习了指针数组, 比如:
int* arr[10];
那要把函数的地址存到⼀个数组中,叫函数指针数组,他又该如何定义呢?举个例子:
int (*parr[3])();

这就是一个简单的函数指针数组,parr先与[ ]结合,说明parr是数组,存放的是int(*)( )类型的函数指针。

6.转移表

下面我们来做一个函数指针数组的应用:转移表

举例:计算机的一般实现

int Add(int x, int y)
{return x + y;
}int Sub(int x, int y)
{return x - y;
}int Mul(int x, int y)
{return x * y;
}int Div(int x, int y)
{return x / y;
}void menu()
{printf("***********************\n");printf("******  0.exit   ******\n");printf("******  1.Add    ******\n");printf("******  2.Sub    ******\n");printf("******  3.Mul    ******\n");printf("******  3.Div    ******\n");printf("***********************\n");
}int main()
{int input;int x, y;do{menu();printf("选择算法->");scanf("%d", &input);switch (input){case 0:break;case 1:printf("输入被运算数->");scanf("%d %d", &x, &y);printf("%d\n", Add(x, y));break;case 2:printf("输入被运算数->");scanf("%d %d", &x, &y);printf("%d\n", Sub(x, y));break;case 3:printf("输入被运算数->");scanf("%d %d", &x, &y);printf("%d\n", Mul(x, y));break;case 4:printf("输入被运算数->");scanf("%d %d", &x, &y);printf("%d\n", Div(x, y));break;default:printf("输入错误,请重新输入\n");break;}} while (input != 0);return 0;
}
使⽤函数指针数组的实现:
int Add(int x, int y)
{return x + y;
}int Sub(int x, int y)
{return x - y;
}int Mul(int x, int y)
{return x * y;
}int Div(int x, int y)
{return x / y;
}void menu()
{printf("***********************\n");printf("******  0.exit   ******\n");printf("******  1.Add    ******\n");printf("******  2.Sub    ******\n");printf("******  3.Mul    ******\n");printf("******  3.Div    ******\n");printf("***********************\n");
}int main()
{int input;int x, y;int (*pf[5])(int, int) = { 0,Add,Sub,Mul,Div };do{menu();printf("选择算法->");scanf("%d", &input);printf("输入被运算数->");scanf("%d %d", &x, &y);printf("%d\n", (*pf[input])(x, y));} while (input);return 0;
}

使用函数指针数组之后代码篇幅大大减少。

7.回调函数
回调函数就是⼀个通过函数指针调用的函数。
如果你把函数的指针(地址)作为参数传递给另⼀个函数,当这个指针被用来调用其所指向的函数时,被调⽤的函数就是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发⽣时由另外的⼀⽅调⽤的,⽤于对该事件或条件进行响应。

针对转移表的改动,我们可以利用回调函数,如下:

int Add(int x, int y)
{return x + y;
}int Sub(int x, int y)
{return x - y;
}int Mul(int x, int y)
{return x * y;
}int Div(int x, int y)
{return x / y;
}void menu()
{printf("***********************\n");printf("******  0.exit   ******\n");printf("******  1.Add    ******\n");printf("******  2.Sub    ******\n");printf("******  3.Mul    ******\n");printf("******  4.Div    ******\n");printf("***********************\n");
}void cacl(int (*pf)(int, int))//回调函数
{int x, y;printf("输入被运算数->");scanf("%d %d", &x, &y);printf("%d\n", (*pf)(x, y));
}int main()
{int input;do{menu();printf("选择算法->");scanf("%d", &input);switch (input){case 0:break;case 1:cacl(Add);break;case 2:cacl(Sub);break;case 3:cacl(Mul);break;case 4:cacl(Div);break;default:printf("输入错误,请重新输入\n");break;}} while (input != 0);return 0;
}

http://www.dtcms.com/wzjs/194504.html

相关文章:

  • asp网站开发设计文档厦门seo网站推广优化
  • wordpress图片切换如何做谷歌优化
  • 开发一个网站要多少钱app广告投放价格表
  • 电子商务网站建设管理郑州网站建设专业乐云seo
  • 怎么做进入网站js特效企业网站推广的形式有
  • 网站建设应注意的问题有哪些百度关键词排名工具
  • 做拼多多网站赚钱吗公司网页制作
  • 济宁专业网站建设竞价排名的服务模式是
  • 青岛专业网站制作团队seo网络优化前景怎么样
  • 建设网站方式有哪些网站运营推广方案
  • 做网站还要数据库吗行业关键词
  • 技术支持 中山网站建设企业网络营销推广平台
  • asp网站发布ftp广州品牌营销服务
  • 同和网站建设网站多久被百度收录
  • 上海各区的网站有哪些公司seo搜索引擎优化步骤
  • 人民日报电子版报纸seo技术网网
  • 棋牌网站哪里做百度手机助手网页版
  • 台州建设局网站信息价制作网站的网址
  • python django 做 网站网站建设流程步骤
  • 下载了模板如何做网站百度站长工具使用方法
  • 网站开发与运营快速提升排名seo
  • phpmysql网站开发项目式教程软文代写平台
  • 做鸡蛋仔冰淇淋店网站2023年10月爆发新冠
  • godaddy wordpress主机seo一键优化
  • 网站建设的一般费用武汉网络推广seo
  • 做av网站赚钱吗专门培训seo的网站
  • wordpress 403天津短视频seo
  • 啊里云服务器怎么做网站什么软件推广效果好
  • 农家乐网站规划与建设方案百度小说排行榜
  • 网站安全建设 应用开发网站联盟广告