C语言 数组指针、指针数组、函数指针

数组指针

一个指向数组的指针。落脚点在指针上面;指针的优先级必定比“[ ]”的优先级高

在这里我们插入一个问题:下面的声明合法吗?

int arr[10], *p = arr;
int brr[3][10], *q = brr;

 第一个声明是合法的。它为一个整型数组分配内存,把p声明为一个指向整型的指针,并把它初始化为指向arr数组的第一个元素。arr和p具有相同的类型:指向整型的指针。但是,第二个是非法的,它正确的创建了brr数组,并把q声明为一个指向整型的指针。但是在这里,q的初始化是不正确的,因为brr并不是一个指向整型的指针,而是一个指向整型数组的指针。

那么,我们该如何声明?

int (*p)[10];

 下标引用的优先级高于间接访问,但由于括号的存在,首先执行的还是间接访问,所以,p是一个指向整型数组的指针。对其加上初始化可得:

int (*p)[10] = brr;

 它指向brr的第1行。

p是一个指向拥有10个整型元素的数组的指针,当把p与一个整数相加减的时候,该整数值首先根据10个整型值的长度进行调整,然后执行加法。所以可以使用这个指针一行一行地在brr中移动。

如果需要一个指针逐个访问整型元素而不是逐行在数组中移动,应该怎么办?

下面两个声明都创建了一个简单的整型指针,并以两种不同的方式进行初始化,指向brr的第一个整型元素:

int *pi = &brr[0][0];
int *pi = brr[0];

增加这个指针的值使它指向下一个整型元素。

指针数组

一个保存指针类型数据的数组。落脚点在数组上面

正如可以创建整型数组一样,也可以声明指针数组。下面举一个例子。

int *ar[10];

为了弄清这个声明,我们假设它是一个表达式,并对它进行求值。

下表引用的优先级高于间接访问,所以在这个表达式中,先执行下标引用,因此,ar是某种类型的数组,它包含的元素个数为10。再取得一个元素之后,随即执行的是间接访问操作,所以它的结果是一个整型值。

那么,ar到底是个什么东西呢?

对数组的某个元素执行间接访问操作后,我们得到一个整型值,所以,ar肯定是个数组,他的元素类型是指向整型的指针。

函数指针

这里我们引入一个简单程序:

#include<stdio.h>
int add(int a, int b)
{
    return a+b;
}
int mul(int a, int b)
{
    return a*b;
}
int main()
{
    int a, b;
    char op;//"+" "*"
    scanf("%d%d", &a, &b);
    scanf("%c",&op);
    int (*pfun)(int, int);//定义一个函数指针,指向add 指向mul
    //(*pfun)声明一个指针变量
    if(op == '+')
    {
        pfun = add;
    }
    else
    {
        pfun = mul;
    }
    int res = pfun(a, b);
    printf("%d", res);
}

结果却出现了一点意外:

2
3
6

输入2,回车;输入3,回车;还没有输入“+”或者“*”,结果直接就出来了,那么这是为什么呢?

原因在于输入缓冲区。我们将断点下到

scanf("%c",&op);

发现,此时的op等于“\n”。

 

 在输完3的时候,回车之后,程序会把回车'\n'读到输入缓冲区中,以%c的形式获取。

对此,我们换一种形式来完成该函数指针的使用。

#include<stdio.h>
#include<string.h>
int add(int a, int b)
{
    return a+b;
}
int mul(int a, int b)
{
    return a*b;
}
int main()
{
    int a, b;
    char op[10] = {0};
    scanf("%d%d", &a, &b);
    scanf("%s",&op);
    int (*pfun)(int, int);
    if(strcmp(op,"+") == 0)
    {
        pfun = add;
    }
    else
    {
        pfun = mul;
    }
    int res = pfun(a, b);
    printf("%d", res);
}

结果为:

2
3
+
5

%d %s 通常是以空格或者\n分割

%d %c 系统无法区分%d和%c之间的\n是换行还是字符,也就是把换行解析成了有效字符。如果我们先%c 再%d就可以避开该问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值