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

淘客返利网站怎么做nba最新排名东西部

淘客返利网站怎么做,nba最新排名东西部,怎么外贸网站推广,wordpress导航主题模板前言:正文1. 字符指针变量2. 数组指针变量2.1 数组指针变量是什么?2.2 数组指针变量怎么初始化 3. 二维数组传参的本质4. 函数指针变量4.1 函数指针变量的创建4.2 函数指针变量的使用4.3 两段有趣的代码4.3.1 typedef关键字 5. 函数指针数组6. 转移表 总结 前言&am…

    • 前言:
    • 正文
      • 1. 字符指针变量
      • 2. 数组指针变量
        • 2.1 数组指针变量是什么?
        • 2.2 数组指针变量怎么初始化
      • 3. 二维数组传参的本质
      • 4. 函数指针变量
        • 4.1 函数指针变量的创建
        • 4.2 函数指针变量的使用
        • 4.3 两段有趣的代码
        • 4.3.1 typedef关键字
      • 5. 函数指针数组
      • 6. 转移表
    • 总结

前言:

这是指针第四篇,主要介绍:字符指针变量、数组指针变量、二维数组传参的本质、函数指针变量、函数指针数组以及函数指针数组的应用——转移表

正文

1. 字符指针变量

在指针的类型中有一种指针类型为字符指针char*
一般使用方式如下:

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

还有一种使用方式如下:

int main()
{const char* ps = "hello C.";printf("%s\n", ps);return 0;
}

代码const char* ps = "hello C";容易让人以为是把字符串hello C放到字符指针ps里了,但是本质是把字符串hello C.首字符的地址放到了ps中。实际是把一个常量字符串的首字符h的地址存放到指针变量ps中。

《剑指offer》中又一道与之相关的题目,代码如下:

#include <stdio.h>
int main()
{char str1[] = "hello C.";char str2[] = "hello C.";const char *str3 = "hello C.";const char *str4 = "hello C.";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;
}

结果
为什么会有这样的结果呢?const修饰常量字符串,str3和strr4是指向同一个字符串的,在C语言中会把常量字符串单独存储到一个内存区域,虽然str3和str4变量名不同,但实际上指向同一片内存空间。然而,用同样的字符串初始化不同数组时会形成不同空间,即不同的内存块。所以str1和str2不同,str3和str4相同。

2. 数组指针变量

2.1 数组指针变量是什么?

先区分一下,之前学过指针数组,它是一种数组,用来存放指针(也就是地址)
数组指针变量,和·指针数组·不同,它是指针变量
举个栗子:

int* pint 表示整型指针变量用来存放整型变量的地址
float* pf表示浮点型指针变量 , 用来存放浮点型数据的地址

数组指针变量存放的是数组的地址,能够指向数组的指针变量。

这里用两个代码经常混淆

int *p1[10];
int(*p2)[10];

哪一个是数组指针变量呢?答案是p2即int(*p2)[10];p1是指针数组,p2先和结合,说明p2是一个指针变量,然后指针指向的是一个大小为 10 个整型的数组,所以p2是一个指针,指向一个数组,叫数组指针。
注意:[]的优先级是高于
的,所以必须加上()保证*和p是一起的

2.2 数组指针变量怎么初始化

数组指针变量是用来存放数组地址的,通过&数组名可以获得数组的地址。例如:

int arr[10] = {0};
&arr;

如果要存放数组的地址,就得存放在数组指针变量中,如下:

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

调试可以看到&arrp的类型是完全一致的。
数组指针类型解析:

描述

3. 二维数组传参的本质

有了数组指针的基础理解,就能够讲一下二维数组传参的本质。

过去二维数组传参给一个函数时,写法如下:

#include <stdio.h>
void test(int a[3][5], int a, int b)
{int i = 0;int j = 0;for(i=0; i<a; i++){for(j=0; j<b; j++){printf("%d ", a[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;
}
0 0 0 1 1 1 2 2 2 3 3 3 4 4 4
0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5
1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6
2 2 2 3 3 3 4 4 4 5 5 5 6 6 6 7 7 7

arr数组 内容如上
实参是二维数组,形参也是二维数组,但是前面说过二维数组其实是一维数组的数组,二维数组的首元素是第一行,是一维数组,所以我们可以这样理解:二维数组数组名是第一行的地址,是一维数组的地址(指针),第一行的一维数组类型就是int [5],so,第一行的地址类型就是数组指针类型int(*) [5].这表示二维数组传参本质上也是传递了地址,传递的是第一行这个一维数组的地址,那么形参也是可以写成指针形式的,如下:

#include <stdio.h>
void test(int (*p)[5], int r, int c)
{int i = 0;int j = 0;for(i=0; i<r; i++){for(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 函数指针变量的创建

函数指针变量应该是用来存放函数地址的,未来通过地址能够调用函数。

函数是有地址的,通过以下测试可以证明:

#include <stdio.h>
void test()
{printf("hehe\n");
}
int main()
{printf("test: %p\n", test);printf("&test: %p\n", &test);return 0;
}

结果

输出结果中test&test的地址相同,函数名就是函数的地址,也可以通过&函数名的方式获得函数的地址。

如果要将函数的地址存放起来,就得创建函数指针变量,函数指针变量的写法和数组指针非常类似。例如:

void test()
{printf("hehe\n");
}
void (*pf1)() = &test;
void (*pf2)()= test;
int Add(int x, int y)
{return x+y;
}
int(*pf3)(int x, int y) = &Add;
int(*pf3)(int, int) = Add;

函数指针类型解析:

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

现在写一个加法的函数,你可能会这样写:

int add(int x,int y)
{return x + y;
}
int main()
{int r = add(2,5);printf("%d",r);return 0;
}

但我们学过上述内容后,通过函数指针调用指针指向的函数,示例代码如下:

#include <stdio.h>
int Add(int x, int y)
{return x+y;
}
int main()
{int(*pf3)(int, int) = Add;printf("%d\n", (*pf3)(2, 3));printf("%d\n", pf3(3, 5));return 0;
}
4.3 两段有趣的代码
(*(void (*)())0)();
void (*signal(int , void(*)(int)))(int);

两段代码均出自《C陷阱和缺陷》这本书。
可以自己写出来理解一下,正常情况我们不会这样写,实在理解不了也没关系,(也可以问问deepseek).

4.3.1 typedef关键字

typedef是用来类型重命名的,可以将复杂的类型简单化。比如将unsigned int重命名为uint

typedef unsigned int uint;

对于指针类型也能重命名,将int*重命名为ptr_t

typedef int* ptr_t;

对于数组指针和函数指针重命名稍有区别。将数组指针类型int(*)[5]重命名为parr_t

typedef int(*parr_t)[5]; 

将函数指针类型void(*)(int)重命名为pf_t

typedef void(*pfun_t)(int);

简化代码2可以这样写:

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

5. 函数指针数组

数组是一个存放相同类型数据的存储空间,已经学习了指针数组,例如int * arr[10];,数组的每个元素是int*

把函数的地址存到一个数组中,这个数组就叫函数指针数组。函数指针数组定义为int (*parr1[3])();parr1先和[]结合,说明parr1是数组,数组的内容是int (*)()类型的函数指针。

6. 转移表

函数指针数组的用途之一是转移表。

例如计算器的一般实现代码如下:

#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(" 0:exit \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");break;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 }; do{printf("*************************\n");printf(" 1:add 2:sub \n");printf(" 3:mul 4:div \n");printf(" 0:exit \n" );printf("*************************\n");printf("请选择:");scanf("%d", &input);if ((input <= 4 && input >= 1)){printf("输入操作数:");scanf("%d %d", &x, &y);ret = (*p[input])(x, y);printf("ret = %d\n", ret);}else if(input == 0){printf("退出计算器\n");}else{printf("输入有误,重新选择\n");}}while (input);return 0;
}

总结

本文就到这里了,如有误,欢迎指正,指针很难,但坚持下去,终有收获,朋友,把这件事坚持下去吧。
敬,不完美的明天。

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

相关文章:

  • 长春火车站到龙嘉机场高铁时刻表seo的作用是什么
  • 网站制作先做数据库还是前台公司产品推广文案
  • 新加坡网站大全河北百度seo关键词
  • 装饰工程设计东莞网站建设超级seo工具
  • 佛山网站建设与设计公司seo综合查询系统
  • 西安高端网站建设哪家好百度引擎搜索入口
  • kuler 网站如何利用互联网进行宣传推广
  • html 动漫网站搜索引擎营销的优缺点及案例
  • 北京网站备案号查询优质友情链接
  • 洛阳网官网seo外链发布技巧
  • 规范门户网站的建设和管理办法怎么做产品推广和宣传
  • 国内4a广告公司有哪些seo整站优化更能准确获得客户
  • 网站上线后想修改网页模板怎么用
  • 网站运营主要是做什么网站seo查询工具
  • 移动端web网站模板优就业seo
  • 涟水建设银行网站营销手段和技巧
  • 杭州高端网站建设公司哪家好自媒体135网站
  • 郑州做网站建设哪家好网站关键词搜索排名
  • 公司网站推广怎么做今日最新国际新闻头条
  • 高校图书馆网站的建设的重要性常见的网站推广方法有哪些
  • 国外做情趣用品比较有名的网站什么叫软文
  • 天凡建设股份有限公司网站个人网站建站流程
  • 建设工程项目管理网站最新国际新闻
  • 广告设计制作公司网站网络搜索工具
  • 设计网站100个免费百度如何做广告
  • 南通动态网站建设十大新媒体平台有哪些
  • 营销型网站深度网搜索引擎排名优化是什么意思
  • 万网ecs放多个网站销售网络平台
  • asp.net网站开发pdf如何建立自己的网站
  • 上海快速建设网站公司网站设计培训