• c++ 变量常量指针练习题


    Q1:在win32 x86模式下,int *p; int **pp; double *q; 请说明p、pp、q各占几个字节的内存单元。

    p 占 4 个字节

    pp 占 4 个字节

    q 占 4 个字节

    Q2常量1、1.0、“1”的数据类型是什么?

    1 是 整形 int

    1.0 是 浮点型 double

    “1” 是 const char *

    Q3 语句:short int a[10]; short int *p = a; sizeof(a)等于sizeof§吗?为什么?

    不一样, sizeof(a) 计算的是开辟的数组的空间大小 ,为 20 字节

    而sizeof§ 计算的是short 类型的指针 p 本身的占用的空间的大小,为 4 个字节

    Q4

    若给出声明: 
    char c, *pc;
    const char cc = 'a'; 
    const char *pcc; 
    char *const cpc = &c; 
    const char * const cpcc = &cc; 
    char *const *pcpc; 
    则下面的赋值哪些是合法的?哪些是非法的?为什么? 
    (1) c = cc; 			(10) *pc = "ABCD"[2]; 
    (2) cc = c; 			(11) cc = 'a'; 
    (3) pcc = &c; 			(12) *cpc = *pc; 
    (4) pcc = &cc; 			(13) pc = *pcpc; 
    (5) pc = &c; 			(14) **pcpc = *pc; 
    (6) pc = &cc; 			(15) *pc = **pcpc; 
    (7) pc = pcc; 			(16) *pcc = 'b'; 
    (8) pc = cpcc; 			(17) *pcpc = 'c'; 
    (9) cpc = pc; 			(18) *cpcc = 'd';
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    (1) 合法 , c 不是 const 类型的变量 ,可以赋值

    (2) 非法 , cc 是 const 类型的变量,不可以赋值

    (3) 合法 , pcc 是一个常量指针,可以更改指向的对象

    (4) 合法, pcc 是一个常量指针,可以更改指向的对象

    (5) 合法 , 类型匹配

    (6) 非法 , pc 是一个 char 类型的 指针, 而 cc 是常量,类型不匹配

    (7) **非法 **, 类型不匹配,pc要求指向char类型的变量,不能用指向const char*类型的pcc赋值。

    (8) 非法 , 类型不匹配,pc要求指向char类型的变量,不能用指向const char*类型的cpcc赋值。

    (9) **非法 **, cpc 是一个指针常量,无法修改指针的指向

    (10)合法 , pc指向的是非const类型的变量,可以赋值,等价于*pc=’C’

    (11) 非法 , 常量 cc 无法被重新赋值

    (12) 合法 , 指针常量 可以 为所指向的对象重新赋值

    (13) 合法 ,pc是非const类型的指针变量,可以用char 类型的值pcpc赋值

    (14) 合法 , pc是非const类型的指针变量,可以用char 类型的值pcpc赋值

    (15) **合法 ** ,*pc代表的是非const类型的字符变量,可以任何字符类型的值赋值。

    (16) 非法 , *pcc代表的字符是const类型的字符变量,不能赋值。

    (17) 非法 , *pcpc代表的是const类型的指针变量,不能赋值。

    (18) 非法 , *cpcc代表的是const类型的只读变量,不能赋值。

    Q5

    C按优先级和结合性解释类型,下述声明是什么意思? 
    (1) typedef void VF_PC_RI(char*, int &);
    (2) typedef VF_PC_RI* P_VF_PC_RI; 
    (3) typedef int &RIFFII(int, int); 
    (4) extern VF_PC_RI funca; 
    (5) extern P_VF_PC_RI ptra; 
    (6) extern void func1 (P_VF_PC_RI *); 
    (7) extern P_VF_PC_RI func2 (int c); 
    (8) P_VF_PC_RI func3 (P_VF_PC_RI a); 
    (9) typedef void (*(**VF_PA_P_PF_V(void))[ ]) (const int);
    (10) int *(*p)[4][2];
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    (1) 定义了一个名为 VF_PC_RI 的函数类型,该函数接受一个 char* 类型的参数和一个 int 引用作为参数,而且这个函数没有返回值

    (2) 定义了一个 名为P_VF_PC_RI的类型,该类型定义了一个指向VF_PC_RI类型的指针。

    (3) 定义了一个名叫 RIFFII 的类型, 该类型定义了一个参数为(int , int ),返回值 为 int 类型的引用的一个函数

    (4) 声明了一个名为 funca 的函数

    (5) 声明了一个类型为P_VF_PC_RI的指针变量ptra

    (6) 声明了一个名为 func1 的函数,该函数接受一个指向 P_VF_PC_RI 类型指针的参数,返回值 为void

    (7) 声明了一个名为 func2 的函数,该函数接受一个 int 参数并返回一个指向 VF_PC_RI 类型函数的指针

    (8) 声明了一个名为 func3 的函数,该函数接受一个 P_VF_PC_RI 类型的参数并返回一个 P_VF_PC_RI 类型的值

    (9) 定义了一个名为 VF_PA_P_PF_V 的函数,该函数不接受参数并返回一个指向指针数组的指针,其中指针数组的元素是指向函数的指针,这些函数接受一个 const int 参数并返回 void

    (10) 定义了一个p 的指针,这个指针指向 4 个元素的数组,每个数组包含2个元素,这两个元素的值都是 int *

    Q6

    下面g()函数的重载声明和定义是否会导致编译错误? 
    float g(int); 
    int g(int); 
    int g(int, int y=3); 
    int g(int, …); 
    int i = g(8);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    会导致编译错误

    • 不能以返回值的不同作为重载的条件 float g(int) 和 int g(int) 冲突
    • g(8) 在调用的时候出现二义性,无法确定是调用int g(int, int y=3)还是int g(int, L)

    **Q7 **定义函数求n(n>=1)个double类型的数的最大值double max1(int n, …)。注意:如果编程测试,建议使用vs2019 ,并且一定要在x86模式(不要在x64)。有兴趣的同学,可以在vs2019-x64下测试,分析为什么得不到正确的结果。

    double maxl(int n,...)
    {
    	double* p = (double*)(&n + 1);
    	double max = p[0];
    	for (int k = 1; k < n; k++)
    	{
    		if (max < p[k])
    		{
    			max = p[k];
    		}
    	}
    	return max;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    用 x64 模式下代码能够运行但是得不到正确的结果,x86 是 64 位,会给每个变量分配 8 个字节,若 n 的地址 为 0x 0000 ,则 下一个 double 的 首地址为 0x 0008 , 但是 double* p = (double*)(&n + 1) 这句话 的意思是 p 的取值到 n 的地址 + sizeof(int) ,就是取值到 0x 0004 ,不能正确取值到 double 的地址,如果 改为 double* * p = (double*)(&n + 2) ,就能正确取值到 0x0008 ,或者 p = (double *)((char *)&n + 8) ,这个等价于 对 n 的地址增加 8 个 字节,也可以取值取到 0x0008

    下面的代码都是可以的

    	double* p = (double*)((char*)&n + 8);
    	double* p = (double*)((short *)&n + 4);
    	double* p = (double*)((int*)&n + 2);
    	double* p = (double*)((double*)&n + 1);
    
    • 1
    • 2
    • 3
    • 4
  • 相关阅读:
    Qt扩展-QCustomPlot绘图基础概述
    B49 - 基于STM32单片机的心率血氧检测与远程定位报警装置
    Makefile 基础(二)—— Makefile 自动推导+ Makefile伪目标
    【数据结构与算法系列3】有序数组的平方 (C++ & Python)
    【云原生系列】云计算概念与架构设计介绍
    C语言实现《三子棋》游戏
    Linux 程序打包
    【Java系列】Java 基础
    CSS属性 - display
    c++视觉---使用轨迹条设置图片的对比度,亮度
  • 原文地址:https://blog.csdn.net/wniuniu_/article/details/132950009