会指针只是你的谎言(三)

一、字符指针变量

我们知道字符指针char*,一般形式:

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

 还有一种:

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

这里不是把hello world存放在字符指针中,而是把hello world的首地址存放在pstr中。 

请看下面的代码:

#include<stdio.h>
int main()
{
    char str1[]="hello world";
    char str2[]="hello world";

    const char*str3="hello world";
    const char*str4="hello world";
    
    if(str1==str2)
        printf("str1 and str2 are same\n");
    else
        printf("str1 and str2 are not same\n");
    if(str3==str4)
        printf("str3 and str4 are same\n");
    else
        printf("str3 and str4 are not same\n");

    return 0;
}

结果是:

这里的str3与str4指向的是同一个内容, 但都存放首元素的地址,指向同一个地方,而str1与str2分别开辟出不同的内存块。

二、数组指针

1、数组指针初始化 

之前我们学了指针数组,指针数组是一种数组,数组存放的是指针。

所以数组指针是一种指针。

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

第一个是指针数组,第二个数组指针。

注意[]的优先级高于*号,所以加上()保证p与*先结合

那么如何初始化?

int main()
{
    int a[10];
    int (*pa)[10]=&a;
    return 0;
}
int (*pa)[10]=&a;
|      |   |
|      |   |
|      |   pa指向数组的元素的个数
|      pa是数组指针的变量名
pa指向的数组的元素的类型
2、二维数组传参的本质

在以前我们对二维数组传参,是这样写的:

void Func(int arr[3][4],int n)
{
;
}

 二维数组其实可以看做每个元素是一维数组的数组,也就是二维数组每个元素是一维数组。那么二维数组的首元素是一维数组。根据数组指针,二维数组的首元素的类型就是int [4],其数组指针类型就是int(*p)[4]。意味着二维数组传参本质上是传递了地址,传递的是第一行一维数组的地址。那么上面可以改写成:

void Func(int (*p)[4],int n)

 三、函数指针变量

什么是函数指针变量?

根据前面所学的字符指针,整型指针,数组指针。函数指针变量是来存放函数的地址。

int main()
{
    test();
    printf("%p\n",test);
    printf("%p\n",&test);
    return 0;
}

结果是一样的, 所以函数是有地址的,函数名就是函数的地址,当然也可以用&函数名的方式取出函数的地址。如果我们要存函数的地址就要创建函数指针变量,函数指针变量的写法与数组指针的形式类似。如下:

void test()
{
    printf("hh");
}
void (*p1)()=test;
void (*p2)()=&test;


int Add(int x,int y)
{
    return x+y;
}
int(*p3)(int,int)=Add;
int (*p4)(int x,int y)=&Add;//x与y可以省略

函数指针类型解析:

int   (*p3)  (int x,int y)
 |      |        |
 |      |        |
 |      |        p3指向函数的参数类型与个数
 |      函数指针变量
p3指向函数返回的类型

函数指针的使用:

#include<stdio.h>
int Add(int x,int y)
{
    return x+y;
}
int main()
{
    int(*p)(int,int)=Add;
    printf("%d\n",(*p)(2,5));
    printf("%d\n",p(5,5));
    return 0;
}

四、typedef关键字

typedef是用来类型重命名的,使复杂的类型变得简单。

比如:

unsigned int写起来不方便,所以:

typedef unsigned int unit;

如果是指针类型:

typedef int* ptr_t;

typedef int(*parr_t)[5];//新的类型必须放在*右边

typedef int(*pfun_t)(int);

 五、函数指针数组

我们已经学习了数组指针,那么把函数指针存放在数组中叫函数指针数组,那么函数指针数组怎么定义?

int (*pf[5])();
函数指针数组的应用------转移表
#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("***** 1.add ******\n");
        printf("***** 2.sub ******\n");
        printf("***** 3.mul ******\n");
        printf("***** 4.div ******\n");
        printf("***** 0.exit ******\n");
        scanf("%d",&input);
        switch (input)
        {
        case 1:
            printf("请输入操作数:");
            scanf("%d %d", &x, &y);
            ret = add(x, y);
            printf("%d\n", ret);
            break;
        case 2:
            printf("请输入操作数:");
            scanf("%d %d", &x, &y);
            ret = sub(x, y);
            printf("%d\n", ret);
            break;
        case 3:
            printf("请输入操作数:");
            scanf("%d %d", &x, &y);
            ret = mul(x, y);
            printf("%d\n", ret);
            break;
        case 4:
            printf("请输入操作数:");
            scanf("%d %d", &x, &y);
            ret = div(x, y);
            printf("%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 input = 1;
    int x, y;
    int(*p[5])(int, int) = { 0,add,sub,mul,div };
    do
    {
        printf("***** 1.add ******\n");
        printf("***** 2.sub ******\n");
        printf("***** 3.mul ******\n");
        printf("***** 4.div ******\n");
        printf("***** 0.exit ******\n");
        scanf("%d", &input);
        if (input >= 1 && input <= 4)
        {
            printf("请输入操作数:");
            scanf("%d %d", &x, &y);
            printf("%d\n", (*p[input])(x, y));
        }
        else if (input == 0)
            printf("退出程序\n");
        else
            printf("输入错误,请重新输入。\n");
    } while (input);
	return 0;
}

 今天先到这,感谢大家观看!

内容概要:2025年大宗商品市场展望报告由世界银行发布,分析了能源、农业、金属和矿物、贵金属以及化肥等多个主要商品类别的市场发展与前景。报告指出,由于全球经济增长放缓和贸易紧张加剧,2025年大宗商品价格预计总体下降12%,2026年进一步下降5%,达到六年来的最低点。油价预计2025年平均为每桶64美元,2026年降至60美元,主要受全球石油消费放缓和供应增加的影响。农业商品价格预计2025年基本稳定,2026年下降3%,其中粮食和原材料价格分别下降7%和2%,但饮料价格上涨20%。金属价格预计2025年下降10%,2026年再降3%,特别是铜和铝价格将显著下跌。贵金属如黄金和白银因避险需求强劲,预计价格将继续上涨。报告还特别关注了疫情后大宗商品周期的变化,指出周期变得更短、更剧烈,主要受到宏观经济冲击、极端天气事件和地缘政治冲突的影响。 适用人群:对全球经济趋势、大宗商品市场动态及其对不同经济体影响感兴趣的政策制定者、投资者、分析师及研究机构。 使用场景及目标:①帮助政策制定者评估全球经济增长放缓对大宗商品市场的影响,从而调整经济政策;②为投资者提供有关未来大宗商品价格走势的风险提示,以便进行投资决策;③协助分析师和研究机构深入理解疫情后大宗商品市场的周期特征,识别潜在的投资机会和风险。 其他说明:报告强调,全球经济增长放缓、贸易紧张加剧以及地缘政治不确定性是影响大宗商品价格的主要因素。此外,极端天气事件和能源转型也对农业和能源商品市场产生了深远影响。报告呼吁各方关注这些结构性变化,并采取相应的风险管理措施。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值