热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

牛客网c语言程序题,牛客网c/c++工程师测试题

1.关于new:new单个对象new在自由空间分配内存,但其无法为其分配的对象命名,因次是无名的,分配之后返回一个指向该对象

1.关于new:

new单个对象

new在自由空间分配内存,但其无法为其分配的对象命名,因次是无名 的,分配之后返回一个指向该对象的指针。

int *pi = new int; // pi指向一个动态分配的,未初始化的无名对象

new多个对象

int *pia = new int[10]; // 10个未初始化int

int *pia2 = new int[10](); // 10个值初始化为0的int

对于一些结构体,我们可以看到()往往表示构造函数,int是基本类型算初始化吧

2.枚举类型

enum string{

x1,

x2,

x3=10,

x4,

x5,

} x;

如果是函数外定义那么是0

如果是函数内定义,那么是随机值,因为没有初始化

3.指针

若有 unsigned char *p1;

unsigned long *p2;

p1 = (unsigned char *)0x1000;

p2 = (unsigned long *)0x2000;

请问 p1+5=( 1005 ) p2+5=( 2014 )

p1指向字符型,一次移动一个字符型,1个字节;p1+5后移5个字节,16进制表示为5;

p2指向长整型,一次移动一个长整型,4个字节,p2+5后移20字节,16进制表示为14。

char每次移动1个字节;short移动2个字节;int ,long ,float移动4个字节;double移动8个字节

4.strlen与sizeof

strlen:实际元素个数

sizeof:数组代销,或者字符串加'\n'共同个数

char str[20]="0123456789";

int a=strlen(str); //a=10;

int b=sizeof(str); //而b=20;

char str[]="Hello";

printf("%d\n",sizeof(str));//6

printf("%d\n",strlen(str));//5

char*p=str;

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

5.虚函数

下面关于虚函数和函数重载的叙述不正确的是

虚函数不是类的成员函数(不正确)

虚函数实现了C++的多态性

函数重载允许非成员函数。

函数重载的调用根据参数的个数、序列来确定,而虚函数依据对象确定

6指针强制类型转换

char str[] = "glad to test something";

char *p = str;

p++;

int *p1 = reinterpret_cast(p);

p1++;

p = reinterpret_cast(p1);

printf("result is %s\n", p);//result is to test something

该题的关键是要认清楚强制类型转换后指针的类型。

p的类型为char *,p++后p指向str数组的第2个元素即字母“l”的位置。

p1的类型为int *,p1++后p1指向的位置增加4个字节,指向str数组中的第6个元素即字母“t”的位置。

因此最后p的内容为“to test something”。

7.析构函数调用顺序

C c;

void main()

{

A*pa=new A();

B b;

static D d;

delete pa;

}

//

考察全局变量,静态局部变量,局部变量空间的堆分配和栈分配

其中全局变量和静态局部变量时从 静态存储区中划分的空间,

二者的区别在于作用域的不同,全局变量作用域大于静态局部变量(只用于声明它的函数中),

而之所以是先释放 D 在释放 C的原因是, 程序中首先调用的是 C的构造函数,然后调用的是 D 的构造函数,析构函数的调用与构造函数的调用顺序刚好相反。

局部变量A 是通过 new 从系统的堆空间中分配的,程序运行结束之后,系统是不会自动回收分配给它的空间的,需要程序员手动调用 delete 来释放。

局部变量 B 对象的空间来自于系统的栈空间,在该方法执行结束就会由系统自动通过调用析构方法将其空间释放。

之所以是 先 A 后 B 是因为,B 是在函数执行到 结尾 "}" 的时候才调用析构函数, 而语句 delete a ; 位于函数结尾 "}" 之前。

8.c++类的内存布局

若char是一字节,int是4字节,指针类型是4字节,代码如下:

class CTest

{

public:

CTest():m_chData(‘\0’),m_nData(0)

{

}

virtual void mem_fun(){}

private:

char m_chData;

int m_nData;

static char s_chData;

};

char CTest::s_chData=’\0’;

(1)若按4字节对齐sizeof(CTest)的值是多少?//12

(2)若按1字节对齐sizeof(CTest)的值是多少?//9

970e6147fbff

测试方法

解析:

1 虚函数表 占一个指针的空间 即 4 virtualvoidmem_fun(){}

2 charm_chData; 1 + 3 对齐 4

3 intm_nData; 4

4 static的成员变量属于类域,不算入对象中 0 staticchars_chData;

1 虚函数表 占一个指针的空间 即 4 virtual void mem_fun(){}

2 char m_chData; 1

3 int m_nData; 4

9.重载与重写

重载在一个类中,参数必须不一致,返回值可以不一致

重写子类方法覆盖父类的,继承过来的,所以返回值类型必须一致或相容(子类)

虚函数重写

class A

{

public:

void FuncA()

{

printf( "FuncA called\n" );

}

virtual void FuncB()

{

printf( "FuncB called\n" );

}

};

class B : public A

{

public:

void FuncA()

{

A::FuncA();

printf( "FuncAB called\n" );

}

virtual void FuncB()

{

printf( "FuncBB called\n" );

}

};

void main( void )

{

B b;

A *pa;

pa = &b;

A *pa2 = new A;

pa->FuncA(); ( 3)

pa->FuncB(); ( 4)

pa2->FuncA(); ( 5)

pa2->FuncB();

delete pa2;

}

//

pa->FuncA(); ( 3)//pa=&b动态绑定但是FuncA不是虚函数,所以FuncA called

pa->FuncB(); ( 4)//FuncB是虚函数所以调用B中FuncB,FuncBB called

pa2->FuncA(); ( 5)//pa2是A类指针,不涉及虚函数,调用的都是A中函数,所以FuncA called FuncB called

pa2->FuncB()

考察父类指针指向子类

10.指针

int FindSubString( char* pch )

{

int count = 0;

char * p1 = pch;

while ( *p1 != '\0' )

{

if ( *p1 == p1[1] - 1 )

{

p1++;

count++;

}else {

break;

}

}

int count2 = count;

while ( *p1 != '\0' )

{

if ( *p1 == p1[1] + 1 )

{

p1++;

count2--;

}else {

break;

}

}

if ( count2 == 0 )

return(count);

return(0);

}

void ModifyString( char* pText )

{

char * p1 = pText;

char * p2 = p1;

while ( *p1 != '\0' )

{

int count = FindSubString( p1 );

if ( count > 0 )

{

*p2++ = *p1;

sprintf( p2, "%i", count );

while ( *p2 != '\0' )

{

p2++;

}

p1 += count + count + 1;

}else {

*p2++ = *p1++;

}

}

}

void main( void )

{

char text[32] = "XYBCDCBABABA";

ModifyString( text );

printf( text );

}

答案:XYBCDCBA1BAA

解析:FindSubString() 函数就是要找到一个先递增再递减且递增和递减的数量相等的回文序列,例如: ABCDCBA ,先是 后一项 = 前一项 ASCII 码 +1 , 后是 后一项 = 前一项 ASCII 码 -1 ,才能返回回文子串的长度,否则返回 0 。

ModifyString() 函数不断寻找上述类型的子串,如果不满足条件,就

*p2++ = *p1++;

当遇到 ABABA 中前一个 ABA 的时候,满足回文子串要求,此时 p1 指向 A BABA , p2 指向 ABABA ; sprintf 重定向修改 ABABA , B 变为 1 ,且跟随一个 ‘\0’ (该函数自动产生的) , 此时,字符串变为 A1‘\0’BA 。

经过 while ( *p2 != '\0' ) 循环之后, p2 指向 A1‘\0’BA , p1 += count + count + 1 之后, p1 指向 A1‘\0’BA 。此时字符串已经被改动,之前的 ABABA 已经不存在,变为 A1‘\0’BA 。

再次进入 while ( *p1 != '\0' ) 循环之后,只能执行 else 部分的命令, p1 指向 p2 指向的元素的后一个,不断将 p1 指向的元素传给 p2 所指向的位置,将原数据覆盖。所以, A1‘\0’BA ,依次变为 A1BBA 、 A1BAA 。即最终结果为 XYBCDCBA1BAA 。

11.数组全排列

void perm(int list[], int k, int m)

{

if ( )//k==m

{

copy(list,list+m,ostream_iterator(cout," "));

cout<

return;

}

for (int i&#61;k; i<&#61;m; i&#43;&#43;)

{

swap(&list[k],&list[i]);

( );//perm(list,k&#43;1,m)

swap(&list[k],&list[i]);

}

}

12.数组作为函数会退化为指针

void example(char acWelcome[]) {

printf("%d", sizeof(acWelcome));

return;

}

int main() {

char acWelcome[] &#61; "Welcome to Huawei Test";

example(acWelcome);//4(32位系统&#xff0c;64位系统则会输出8)

printf("\n%d\n", sizeof(acWelcome));//23

return 0;

}

数组作为函数的参数是会退化为函数指针的&#xff0c;想想看&#xff0c;数组作为函数参数的时候经常是需要传递数组大小的

13.深浅拷贝操作

#include

using namespace std;

class MyClass

{

public:

MyClass(int i &#61; 0)

{

cout <

}

MyClass(const MyClass &x)

{

cout <<2;

}

MyClass &operator&#61;(const MyClass &x)

{

cout <<3;

return *this;

}

~MyClass()

{

cout <<4;

}

};

int main()

{

MyClass obj1(1), obj2(2);

MyClass obj3 &#61; obj1;

return 0;

}

解析&#xff1a;

关键是区分 浅/深拷贝操作 和 赋值操作:

没有重载&#61;之前&#xff1a;

A a ;

A b;

a &#61; b;

这里是赋值操作。

A a;

A b &#61; a;

这里是浅拷贝操作。

重载 &#61; 之后&#xff1a;

A a ;

A b;

a &#61; b;

这里是深拷贝操作(当然这道题直接返回了&#xff0c;通常我们重载赋值运算符进行深拷贝操作)。

A a;

A b &#61; a;

这里还是浅拷贝操作。

所以 MyClass obj3 &#61; obj1; 调用的是拷贝构造函数。

如果写成 MyClass obj3; obj3 &#61; obj1; 输出的结果就是 1203444



推荐阅读
  • 本文提供了多种方法来计算给定年份和月份的起始日和结束日,并进一步探讨了如何根据年、月、周获取特定周的起始日和结束日。 ... [详细]
  • 本文详细解析了Java中throw和throws的关键区别,同时涵盖了JDK的定义、Java虚拟机的关键约定、Java的跨平台性、自动垃圾回收机制、源文件结构、包的概念及作用等多个核心知识点,旨在帮助学生更好地准备Java期末考试。 ... [详细]
  • 本文详细探讨了Java命令行参数的概念、使用方法及在实际编程中的应用,包括如何通过命令行传递参数给Java程序,以及如何在Java程序中解析这些参数。 ... [详细]
  • 本文介绍了如何使用JFreeChart库创建一个美观且功能丰富的环形图。通过设置主题、字体和颜色等属性,可以生成符合特定需求的图表。 ... [详细]
  • KMP算法是一种高效的字符串模式匹配算法,能够在不进行回溯的情况下完成匹配,其时间复杂度为O(m+n),其中m和n分别为文本串和模式串的长度。本文将详细介绍KMP算法的工作原理,并提供C语言实现。 ... [详细]
  • 本文详细介绍了Java中的注解功能,包括如何定义注解类型、设置注解的应用范围及生命周期,并通过具体示例展示了如何利用反射机制访问注解信息。 ... [详细]
  • 本文详细介绍了Java的安装、配置、运行流程以及有效的学习方法,旨在帮助初学者快速上手Java编程。 ... [详细]
  • 本文深入探讨了 Linux 系统下进程的内存布局,包括栈、堆、BSS 段、数据段和代码段的特性与功能,并进一步分析了 C++ 程序中的内存管理特点。 ... [详细]
  • 1、字符型常量字符型常量指单个字符,是用一对单引号及其所括起来的字符表示。例如:‘A’、‘a’、‘0’、’$‘等都是字符型常量。C语言的字符使用的就是 ... [详细]
  • 本文详细介绍了Java集合框架中的Collection体系,包括集合的基本概念及其与数组的区别。同时,深入探讨了Comparable和Comparator接口的区别,并分析了各种集合类的底层数据结构。最后,提供了如何根据需求选择合适的集合类的指导。 ... [详细]
  • 本文介绍了如何在 Flutter 应用程序中使用单例模式创建一个全局唯一的数据管理类,以确保在整个应用生命周期中数据的一致性和可访问性。 ... [详细]
  • Chapter11&12:DefocusBlur&FinalScene在Camera.h中修改如下:#pragmaonce#define_USE ... [详细]
  • 前言无论是对于刚入行工作还是已经工作几年的java开发者来说,面试求职始终是你需要直面的一件事情。首先梳理自己的知识体系,针对性准备,会有事半功倍的效果。我们往往会把重点放在技术上 ... [详细]
  • 本文详细介绍了如何正确安装Java EE SDK,并解决在安装过程中可能遇到的问题,特别是关于servlet代码在Apache Tomcat 10中无法运行的情况。 ... [详细]
  • JavaScript:简洁与复杂之间的平衡
    本文探讨了在编写JavaScript教程时,如何在保持内容简洁的同时,确保初学者能够理解并应用实际开发中的复杂问题。文章通过具体示例分析了不同层次的JavaScript代码实现。 ... [详细]
author-avatar
禁灭19
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有