【笔记】关于指针的一些题

本文深入探讨了C++中结构体与指针的高级用法,包括结构体成员的内存布局、指针操作及数组作为函数参数的行为。通过具体代码示例,解析了结构体指针的访问方式、字节对齐规则、数组退化为指针的特性,以及复杂类型的声明技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.有以下代码:

//链接:https://www.nowcoder.com/questionTerminal/453e0f5f311743af87e40fee43241758
//来源:牛客网

struct A
{
    bool b;
    int arr[2];
    int i;
    int j;
};
int main()
{
    A a;
    a.b = false;
    a.arr[0] = 1;
    a.arr[1] = 2;
    a.i = 20;
    a.j = 30;
    *(a.arr + 1) = 40;
    A*p = 0;
    unsigned int q = (unsigned int)(&p->i));
    (*(int*)((char*)&a +q)) = -50;
     return 0;
}

当main函数返回之前,请问以下哪些说法是错误的:(    )

  • A. a.b的值是false
  • B. arr[0]的值是1
  • C. a.i的值是20
  • D. a.j的值是30

答案C。

参考网友答案如下:

这里主要是最后几行代码怎么解释?

A*p = 0;

unsigned int q = (unsigned int)(&p->i));

(*(int*)((char*)&a +q)) = -50;

考点1:结构体指针,结构体指针的访问方式为(p->i)

考点2:->优先级大于&,故而这里是取对象的成员相对地址

考点3:考虑字节4对齐,bool b后面有3个空字节,所以i的地址就是12. 即q=12

考点4:(char*)&a +q 先把a的地址转换成指向char型(即1个Byte)指针,然后指针往后移动q个Byte。

所以最后得出的结果是a.i的值为-50。

2.关于数组做参数的题:

下面函数的执行结果是输出

2

3

4

5

func(char para[100])

{

    void *p = malloc(100);

    printf("%d, %d\n", sizeof(para), sizeof(p));

}

答案:4,4

解析:

数组作函数参数时候退化为指针,sizeof 为普通指针大小

若直接对数组 sizeof 则结果为数组总长

1

2

3

4

5

6

7

8

void f(char b[100]){

    printf("sizeof in f: %d\n", sizeof(b));

}

 

int main(){   char p[100];

    printf("sizeof in main: %d\n", sizeof(p));

    f(p);

结果输出:

sizeof in main: 100

sizeof in f: 4

 

3.

声明一个指向含有10个元素的数组的指针,其中每个元素是一个函数指针,该函数的返回值是int,参数是int*,正确的是()

A.(int *p[10])(int*)
B. int [10]*p(int *)
C. int (*(*p)[10])(int *)
D. int ((int *)[10])*p

正确答案: C   

先看未定义标识符p,p的左边是*,*p表示一个指针,跳出括号,由于[]的结合性大于*,所以*p指向一个大小为10的数组,即(*p)[10]。左边又有一个*号,修释数组的元素,*(*p)[10]表示*p指向一个大小为10的数组,且每个数组的元素为一个指针。跳出括号,根据右边(int *)可以判断(*(*p)[10])是一个函数指针,该函数的参数是int*,返回值是int。所以选C。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值