牛客网错题整理(C/C++基础知识回顾)(1)

本文回顾了C/C++的基础知识,包括函数返回局部变量的生存周期问题,const用法的详细解析,以及指针转换的各种情况。同时,讨论了字符数组的输入、虚函数、预定义标识符、构造函数初始化列表等重要概念。
摘要由CSDN通过智能技术生成

1.如下代码输出结果是什么【生存周期问题】

#include<stdio.h>
char *myString()
{
    char buffer[6] = {
  0};
    char *s = "Hello World!";
    for (int i = 0; i < sizeof(buffer) - 1; i++)
    {
        buffer[i] = *(s + i);
    }
    return buffer;
}
int main(int argc, char **argv)
{
    printf("%s\n", myString());
    return 0;
}
  • A Hello
  • B Hello World!
  • C Well
  • D 以上全部不正确

答案选择D,用VS2017实测是输出烫烫烫。
做题时候想的是没有结束符,但看评论区好像并没有人提到?
参考解析推荐最高回复

函数char *myString()中没有使用new或者malloc分配内存,所有buffer数组的内存区域在栈区,随着char *myString()的结束,栈区内存释放,字符数组也就不存在了,所以会产生野指针,输出结果未知

比较认同的解释:

在c语言层面上,地址空间的值随时可能被覆盖。被覆盖的原因也是这玩意儿在栈空间,而且栈底指针已经向高地址偏移了,那么这片空间在下一个函数执行时,如果有局部变量,将会对应到下一个函数的局部变量上面。下一个函数是啥?printf,所以关键是看printf有没有申请局部变量,并且修改局部变量的值。被调函数返回局部数组是允许的。

返回局部栈变量的地址并引用它,这叫做undefined behavior。语言层面对这种东西不做规定,所以是一个实现相关问题。因此,选择D是自然的结果。

2.以下选项如果可以初始化正确,那么就会初始化正确,那么以下哪种语法在C++中初始化以后编译会错误?其中X为一C++类【const用法】

  • A const X* x
  • B X const* x
  • C const X const* x
  • D X* const x

答案【CD】
const在*前面 都表示*x不可修改
C中*前出现两个const,g++编译器提示duplicate’const’,语法错误
D中const在*后面,表示指针不可修改,需要初始化。const类型的指针声明时必须初始化
p.s*X* const x放在类中当一个成员,是没有错误的。*



const补充

const 限定一个对象为只读属性。
先从一级指针说起吧:
(1)const char p 限定变量p为只读。这样如p=2这样的赋值操作就是错误的。
(2)const char *p p为一个指向char类型的指针,const只限定p指向的对象为只读。这样,p=&a或 p++等操作都是合法的,但如*p=4这样的操作就错了,因为企图改写这个已经被限定为只读属性的对象。
(3)char *const p 限定此指针为只读,这样p=&a或 p++等操作都是不合法的。而*p=3这样的操作合法,因为并没有限定其最终对象为只读。
(4)const char *const p 两者皆限定为只读,不能改写。
有了以上的对比,再来看二级指针问题:
(1)const char **p p为一个指向指针的指针,const限定其最终对象为只读,显然这最终对象也是为char类型的变量。故像**p=3这样的赋值是错误的,而像*p=? p++这样的操作合法。
(2)const char * const *p 限定最终对象和 p指向的指针为只读。这样 *p=?的操作也是错的。
(3)const char * const * const p 全部限定为只读,都不可以改写。
总结一下就是看const后跟的是什么,*为对象,变量为指针(针对const指针情况)


3.字符串作为常量值,存在内存常量区。

char *p="hello"; return p == "hello"; //返回1

进一步:

char *p1 = "hello";char *p2= "hello"; //p1 == p2
//但是&p1!=&p2 

4.四种转换方式

  • reinterpret_cast:
    一个指针转化为其他类型的指针时,不做类型检测,操作结果是一个指针指向另一个指针的值的二进制拷贝;
  • static_cast:
    允许执行隐式转换和相反的转换操作,父类转换为子类是强制转换Son *son=static_cast(father),而子类转换为父类就是隐式转换;
  • dynamic_cast:
    用于对象的指针和引用,当用于多态类型转换时,
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值