笔试面试中指针的那些事

1.指针的大小

如下代码:
int main(){
char\* p = "hello";
cout<<sizeof(p)<<endl;
}

请问输出是多少?
答:此处考点容易和字符串大小或者字符串长度混淆,此处sizeof求取的是指针p本身所占用的大小,我们知道指针保存的是地址值,那么在x86平台下,地址值占用4个字节的空间大小;在x64平台下,地址值占用8个字节的大小。默认是x86平台,因此输出为4。

2.指针与数组

笔试题:写出一个数组指针和指针数组的声明。
数组指针:int (*p)[10]; //p是一个指向拥有10个int元素数组的指针
指针数组:int* p[10]; //p是一个指向拥有10个元素都为int*的数组的指针

奇特的声明

常用的修饰符:
*:表示一个指针
():表示一个函数
[]:表示一个数组

C/C++中允许同时使用多余1个的修饰符,这样就使得可以创建如下各种各样的类型:

int board[8][8]; //int数组的数组,即二维int数组
int **ptr; //指向int指针的指针,二维指针
int* risks[10]; //具有10个元素的数组,每个元素是一个指向int的指针(指针数组)
int (*rusks)[10]; //一个指针,指向具有10个元素的int数组
int * oof[3][4]; //一个3x4的数组,每个元素是一个指向int的指针
int (*uuf)[3][4]; //一个指针,指向3x4的int数组
int (*uof[3])[4]; //一个具有3个元素的数组,每个元素是一个指向具有4个元素的int数组的指针

弄清楚这些声明的诀窍在于理解运算符的优先级
(1) 圆括号(),方括号[]的优先级最高(这两者处于同一级别),结合性都是从左到右
(2) 取值*,地址 &优先级次之,结合性是从右到左

因此对于上述声明类型,可以分析如下:
1. 表示一个数组的[]和表示一个函数的()具有同样的优先级,这个优先级高于间接运算符*的优先级。这意味着下面的声明使得risks是一个指针数组,而不是一个指向数组的指针:
int* risks[10];
2. []和()具有相同的优先级,都是从左到右结合的,所以下面的声明在应用方括号之前先将*和rusks组合在一起。这意味着rusks是一个指向具有10个int的数组的指针:
int (*rusks)[10];
将上述规则应用到其他几个声明即可得到各自的含义。

3.指针与函数

  1. 首先,函数指针是什么意思?假定一个指针指向一个int变量,它保存着这个int变量在内存中存储的地址。同样,函数也有地址(代码段),这是因为函数的机器语言实现是由载入到内存的代码组成。指向函数的指针中保存这函数代码起始处的地址。其次声明一个数据指针的时候,必须声明它指向的数据的类型。当声明一个函数指针时,必须声明它指向的函数类型。要指定函数类型,就要指出函数的返回类型以及函数的参数类型。考虑一下函数原型:
    void ToUpper(char*); //把字符串转换为大写
    函数ToUpper()的类型是“具有char*类型参数,返回类型是void的函数”。要声明一个指向这种类型函数的指针pf,可以这样做:
    void (*pf)(char* ); //pf是一个指向函数的指针
    提示:
    如果需要声明一个指向特定函数类型的指针,可以首先声明一个该类型的函数,然后用(*pf)形式的表达式代替函数名称;pf就成为可指向那种类型函数的指针了

  2. 指针函数是一个比较简单的概念,即函数的返回值是一个指针。本质上讲的是一个函数,如下的函数形式就是指针函数:
    void* pf(char *)

猜你喜欢

转载自blog.csdn.net/owen7500/article/details/52863902