牛客网练习题整理(1)

(1)关于浮点型double

以下数字在表示为double(8字节的双精度浮点数)时存在舍入误差的有()。

2的平方根   
10的30次方
0.1
0.5
100

A. 2的平方根,本身就是无限小数,因此肯定有舍入误差

B. 10的30次方,明显超出了double的数据存储范围,故有舍入误差

C. 0.1不能用2的负整数次方来表示,因此有误差

D. 0.5 = 2^(-1),因此没有误差

E. 100的二进制表示是:0110 0100,因此没有误差

(2)结构体字节对齐

32位机器上定义如下结构体:

struct xx
{
    long long _x1;
    char _x2;
    int _x3;
    char _x4[2];
    static int _x5;
};
int xx::_x5;
 

1

请问sizeof(xx)的大小是()

 按照8位字节对齐,所以是24,不是20

(3)关于map的题

#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
scanf("%d", &n);
map <int, int> xs;
map <int, int> ys;
map < pair <int, int>, int > zs;
long long ans = 0;
for (int i = 0; i < n; i++) {
int x, y;
scanf("%d %d", &x, &y);
ans += (xs[x]++);
ans += (ys[y]++);
ans -= (zs[make_pair(x, y)]++);
}
cout << ans << endl;
return 0;
}
输入:
6
0 0
0 1
0 2
-1 1
0 1
1 1
则上述程序输出为(11 )

(4)在C++中,为了让某个类只能通过new来创建(即如果直接创建对象,编译器将报错),应该()

将析构函数设为私有

(5)关于main函数的第二个参数

136

(6)关于虚函数的描述

什么是虚函数?简单地说,那些被virtual关键字修饰的成员函数,就是虚函数,java中普通成员函数就是虚函数,

A. 两者在概念和使用方式上当然是不同的。如果是涉及的是同个类中的对象,那就是的重载。如果两个类是父类与子类的关系,调用的函数是它们都有的,那么是虚函数调用

B. 可以加上final关键字变成非虚函数

C. 在C++中,基类指针可以指向派生类对象,以及基类中拥有虚函数,是支持多态性的前提,但虚函数的存在是为了多态。

D. 如果不是纯虚函数,也就是基类不是抽象类的话,虚函数在子类中可以不实现!

E. 虚函数(virtual):可以由子类继承并重写的函数,后期绑定

F. 假设基类中采用的是非虚析构函数,当删除基类指针指向的派生类对象时就不会触发动态绑定,因而只会调用基类的析构函数,而不会调用派生类的析构函数。那么在这种情况下,派生类中申请的空间就得不到释放从而产生内存泄漏。

(7)

有以下程序

1

2

3

4

5

6

7

8

9

10

11

12

13

#include <stdio.h>

#include <stdlib.h>

void fun ( double *pl,double *p2,double *s)

{

    s = ( double*) calloc ( 1,sizeof(double));

    *s = *pl + *(p2+1);

main( )

{

    double a [2] = {1.1,2.2},b [2] = {10.0,20.0}, *s = a;

    fun (a,b,s);

    printf ( "%5.2f\n",* s) ;

程序的输出结果是?

1.10

s没有被改变,原因是s = ( double*) calloc ( 1,sizeof(double));改变了指针变量。

s中存放的地址值改变了,所以*S赋值时没有给main() 的s赋值

函数名: calloc

函数原型:void* calloc(unsigned int num,unsigned int size);

功能:在内存的动态存储区中分配num个长度为size的连续空间,函数返回一个指向分配起始地址的指针;如果分配不成功,返回NULL。

calloc在动态分配完内存后,自动初始化该内存空间为零,而malloc不做初始化,分配到的空间中的数据是随机数据。其中malloc的简介如下:

  • 原型:extern void* malloc(unsigned int size); [1] 

  • 功能:动态分配内存;

  • 注意:size仅仅为申请内存字节大小,与申请内存块中存储的数据类型无关,故编程时建议通过以下方式给出,"长度 * sizeof(数据类型)"; [2] 

(8)(反码则是除符号位外,其余位取反:1111 1001
             补码则是反码+1,即: 1111 1010

              扫描法(知道补码求源码))

union Test

 {

    char a[4];

    short b;

 };

 Test test;

 test.a[0]=256;

 test.a[1]=255;

 test.a[2]=254;

 test.a[3]=253;

 printf("%d\n",test.b);

问题:在80X86架构下,输出什么值

char类型的取值范围是-128~127,unsigned char的取值范围是0~255

这里a[0]=256,出现了正溢出,将其转换到取值范围内就是0,即a[0]=0;

同理,a[1]=-1, a[2]=-2, a[3]=-3,在C语言标准里面,用补码表示有符号数,故其在计算机中的表示形式如下:

a[0]=0,     0000 0000

a[1]=-1,    1111 1111

a[2]=-2,    1111 1110

a[3]=-3,    1111 1101

short是2字节(a[0]和a[1]),由于80X86是小端模式,即数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中,在本例中,a[0]中存放的是b的低位,a[1]中存放的是b的高位,即b的二进制表示是:1111 1111 0000 0000,表示-256,故选B。

short为16位,从a的首地址开始前16位为b。

80X86架构 小端寻址(低位低地址,高位高地址),故 b = 1111 1111 0000 0000 (机器码  是一个补码)。

符号位为1,因此b为负数。 所以源码  =1000 0001 0000 0000.

负数原码 = 取反(补码-1)=~( 111 1111 0000 0000 - 1 )= 000 0001 0000 0000=256。

故b=-256。

(9)大端  小端

(1)低地址存储低字节即为小端存储;高地址存储高字节即为小端存储;

     (2)低地址存储高字节即为大端存储;高地址存储低字节即为大端存储;

对于一个32位的机器,一个字节为8位,字是最小的存储单位是字节,32位对应有4个字节。

 如果对一个32位的数据,要求从大端存储转换为小端存储的代码为:

uint32_t swap_endian(uint32_t val) {
    val = ((val << 8) & 0xFF00FF00) | ((val >> 8) & 0xFF00FF);
    return (val << 16) | (val >> 16);
}

(10)下面有关回调函数的说法,错误的是?

正确答案: C   你的答案: C

回调函数就是一个通过函数指针调用的函数
回调函数可能被系统API调用一次,也可能被循环调用多次
回调函数本身可以是全局函数 ,静态函数和某个特定的类的成员函数
回调函数可用于通知机制

考察点:this指针

 

核心就是类成员函数需要this指针访问函数,而全局或者静态函数不需要this指针。

简言之,类的成员函数需要隐含的this指针 而回调函数没有办法提供。

 

基础概念:

      回调函数就是一个通过函数指针调用的函数。

       如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。

       回调函数不是由该函数的实现方法直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值