指针与函数、数组和Const

本文解析了复杂的C语言数据声明,包括多级指针、数组、函数指针等,并提供了具体的例子帮助理解。同时,文章还解答了如何正确声明不同类型指针的问题。

1、下面的数据声明都代表什么? ­

(1)float (**def)[10];  (2)double* (*gh)[10];  (3)double (*f[10])(); ­

(4)int* ((*b)[10]);     (5)long (*fun)(int);      (6)int (*(*F)(int, int))(int); ­

答:(1)def是一个二级指针,它指向的是一个一维数组的指针,数组的元素都是float。 ­

(2)gh是一个指针,它指向一个一维数组,数组元素都是double*。 ­

(3)f是一个数组,f有10个元素,元素都是指向函数的指针(即函数指针),指向的函数类型是没有参数且返回double的函数。 ­

(4)就跟"int* (*b)[10]"是一样的,b是一个指向一维数组的指针。 ­

(5)函数指针。 ­

(6)F是一个函数的指针,指向的函数的类型是有两个int参数并且返回一个函数指针的函数,返回的函数指针指向有一个int参数且返回int的函数。 ­

­

2、一个指向整型数组的指针定义为(): ­

A.int (*ptr)[]  B.int *ptr[]  C.int *(ptr[])  D.int ptr. ­

答:A. ­

B:指针数组,ptr[]里面存的是地址。 ­

C:与B相同。 ­

D:普通的数组。 ­

­

3、用变量a给出下面的定义[中国台湾某著名CPU生产公司2005年面试题]: ­

a.一个整型数 ­

b.一个指向整型数的指针 ­

c.一个指向指针的指针,它指向的指针式指向一个整型数 ­

d.一个有10个整型数的数组 ­

e.一个有10个指针的数组,该指针指向一个整型数 ­

f.一个指向有10个整型数数组的指针 ­

g.一个指向函数的指针,该函数有一个整型参数并返回一个整型数 ­

h.一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数 ­

答:a. int a; ­

b. int *a; ­

c. int **a; ­

d. int a[10]; ­

e. int *a[10]; ­

f. int (*a)[10]; ­

g. int (*a)(int); ­

h. int (*a[10])(int); //错以为是int (int (*a)(int))[10];­

 

4、要求:写出函数指针、函数返回指针、const指针、指向const的指针、指向const的const指针。
答:void (*f)(); void* f(); int* const p; const int *p; const int* const p;
cosnt int *p表示声明一个指向一个int常量的指针p,不能通过p来改变它所指向的数据值,但可以改变p本身的值。
int* const p表示声明一个指针常量或常指针p,p指向的是一个int值。不能改变p的值,但可以改变p所指向的数据值。这种方式必须赋予指针变量p一个初值。
const int* const p表示声明一个指向int常量的指针常量p,p本身不可以改变,p所指向的常量也不可以改变。并且必须在声明时赋初值。
注:原题答案以为const int *p;/*p为const指针*/,int* const p;/*p为指向const的指针*/,以为有误!

### C++ 中函数指针数组 `const` 关键字结合使用的说明 在 C++ 编程中,当涉及到函数指针数组并希望利用 `const` 来增强程序的安全性清晰度时,可以通过多种方式来实现这一点。下面将详细介绍几种不同的场景及其对应的语法结构。 #### 场景一:只读的函数指针数组 如果目标是创建一个不可修改其成员指向的函数地址的函数指针数组,则可以在声明该数组时加上顶层 `const`: ```cpp // 定义两个简单整数到整数转换函数作为例子 int addOne(int n) { return n + 1; } int doubleValue(int n) { return n * 2; } // 声明一个包含两个元素的函数指针数组,并初始化它们分别指向addOnedoubleValue void example1() { int (*const funcPtrArray[])(int) = {addOne, doubleValue}; // 下面这行会报错,因为funcPtrArray本身被标记为了const // funcPtrArray[0] = nullptr; } ``` 此代码片段展示了如何通过给整个数组加 `const` 属性使其成为只读状态[^2]。 #### 场景二:指向常量返回类型函数指针数组 有时可能需要一组函数都返回相同类型的常数值,在这种情况下应该让每个函数指针对应于具有特定签名——带有 `const` 返回值类型——的函数: ```cpp // 修改之前的函数以返回const int* const int* getConstIntPointer(const int& value) { static const int result = value; return &result; } // 创建一个存储上述类型函数指针数组 void example2() { const int* (*funcPtrArray[])(const int&) = {getConstIntPointer}; // 调用其中一个函数并通过参数传递具体值 auto ptr = funcPtrArray[0](42); cout << "*ptr=" << *ptr << endl; // 尝试改变所指向的内容将会失败编译 //*ptr = 99; // 错误: cannot assign to variable 'ptr' with const-qualified type 'const int' } ``` 这里强调了即使我们试图更改由这些函数产生的结果也不会成功,因为已经明确了返回的对象为不可变对象[^3]。 #### 场景三:完全限定的 `const` 函数指针数组 最后一种情况是对函数指针本身的定义施加更严格的约束条件,即不仅防止重定位(重新分配),而且也阻止调用者间接地经由此路径去篡改原始数据源中的任何东西: ```cpp // 构建一系列接受固定输入但不改变内部状态的操作符 class Calculator { public: static const int multiplyByTwo(const int x) {return x * 2;} static const int squareTheNumber(const int y) {return y * y;} }; // 初始化一个含有多个此类静态成员函数函数指针列表 void example3() { typedef const int (Calculator::*FuncType)(const int)const; FuncType const funcPtrArray[] = {&Calculator::multiplyByTwo,&Calculator::squareTheNumber}; Calculator calcInstance; for(auto&& fn : funcPtrArray){ cout<<calcInstance.*fn(5)<<endl; } } ``` 在这个实例里,所有的操作都被严格限制在一个安全范围内工作,没有任何副作用影响外部环境或者破坏原有逻辑的一致性[^4]。 综上所述,合理运用 `const` 可以为涉及复杂的数据交换机制提供额外保护层的同时保持良好的可维护特性。
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值