热门标签 | 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泛型:JDK 5的新特性
    本文详细介绍了Java泛型的概念及其在JDK 5中的应用,通过具体代码示例解释了泛型的引入、作用和优势。同时,探讨了泛型类、泛型方法和泛型接口的实现,并深入讲解了通配符的使用。 ... [详细]
  • 本文详细探讨了KMP算法中next数组的构建及其应用,重点分析了未改良和改良后的next数组在字符串匹配中的作用。通过具体实例和代码实现,帮助读者更好地理解KMP算法的核心原理。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • 2023年京东Android面试真题解析与经验分享
    本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ... [详细]
  • 从 .NET 转 Java 的自学之路:IO 流基础篇
    本文详细介绍了 Java 中的 IO 流,包括字节流和字符流的基本概念及其操作方式。探讨了如何处理不同类型的文件数据,并结合编码机制确保字符数据的正确读写。同时,文中还涵盖了装饰设计模式的应用,以及多种常见的 IO 操作实例。 ... [详细]
  • 题目Link题目学习link1题目学习link2题目学习link3%%%受益匪浅!-----&# ... [详细]
  • 本文探讨了 C++ 中普通数组和标准库类型 vector 的初始化方法。普通数组具有固定长度,而 vector 是一种可扩展的容器,允许动态调整大小。文章详细介绍了不同初始化方式及其应用场景,并提供了代码示例以加深理解。 ... [详细]
  • 本题探讨了一种字符串变换方法,旨在判断两个给定的字符串是否可以通过特定的字母替换和位置交换操作相互转换。核心在于找到这些变换中的不变量,从而确定转换的可能性。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 主要用了2个类来实现的,话不多说,直接看运行结果,然后在奉上源代码1.Index.javaimportjava.awt.Color;im ... [详细]
  • 题目描述:给定n个半开区间[a, b),要求使用两个互不重叠的记录器,求最多可以记录多少个区间。解决方案采用贪心算法,通过排序和遍历实现最优解。 ... [详细]
  • 深入理解C++中的KMP算法:高效字符串匹配的利器
    本文详细介绍C++中实现KMP算法的方法,探讨其在字符串匹配问题上的优势。通过对比暴力匹配(BF)算法,展示KMP算法如何利用前缀表优化匹配过程,显著提升效率。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • SQLite 动态创建多个表的需求在网络上有不少讨论,但很少有详细的解决方案。本文将介绍如何在 Qt 环境中使用 QString 类轻松实现 SQLite 表的动态创建,并提供详细的步骤和示例代码。 ... [详细]
  • 本文详细探讨了C语言中指针的概念,特别是指针在变量和数组中的应用。通过实例讲解,帮助读者更好地掌握指针的使用方法。 ... [详细]
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社区 版权所有