牛客错题集C++(一)

 题目一  类的构造与析构函数

#include <iostream>
using namespace std;

class A
{
private:
    static int a,b;
public:
    A()
    {
        a++;
        cout<<"A调用构造函数: "<<a<<endl;
    }

    Show()
    {
        cout<<"I am a class project!"<<endl;
    }

    ~A()
    {
        b++;
        cout<<"A调用析构函数: "<<b<<endl;
    }
};

int A::a=0;
int A::b=0;

int main()
{
    A *pa=new A[10];
    delete [] pa;
    cout<<endl;

    A *pb=new A[10];
    delete pb;
    pb[1].Show();
    return 0;
}

第二个只是删除第一个对象。

题目二 关于C语言中输入输出问题

1 scanf函数在碰到空格,回车或Tab键时认为输入结束,且把他们仍然留在输入缓冲中

2 getch():

所在头文件:conio.h

函数用途:从控制台读取一个字符,但不显示在屏幕上

例如:

char ch;或int ch;

getch();或ch=getch();

用getch();会等待你按下任意键,再继续执行下面的语句;

用ch=getch();会等待你按下任意键之后,把该键字符所对应的ASCII码赋给ch,再执行下面的语句。

3 getchar():

该函数声明在stdio.h头文件中,使用的时候要包含stdio.h头文件。如:

#include<stdio.h>

int getchar(void);

getch与getchar基本功能相同,差别是getch直接从键盘获取键值,不等待用户按回车,只要用户按一个键,getch就立刻返回, getch返回值是用户输入的ASCII码,出错返回-1.输入的字符不会回显在屏幕上.getch函数常用于程序调试中,在调试时,在关键位置显示有关的结果以待查看,然后用getch函数暂停程序运行,当按任意键后程序继续运行.

4 gets(str): 以回车结束读取,使用'\0'结尾.回车符'\n'被舍弃没有遗留在缓冲区。可以用来输入带空格的字符串。

题目三 数组首地址为常量

a为 char* const 类型的指针常量 不能对其赋值

题目四 C++中参数入栈问题

函数参数的入栈顺序,从右到左;

栈的存储是从高地址到低地址。

题目五 运算符的优先级和短路问题

先++,在短路,最后赋值,y没有参与计算,因此值没有变化。

碰到*P++就相当于碰到*(P++)

题目六 32系统和64位系统中不同类型数据占据的字节长度

32位操作系统

char :1个字节(固定)

*(即指针变量): 4个字节(32位机的寻址空间是4个字节。同理64位编译器)(变化*)

short int : 2个字节(固定)

int: 4个字节(固定)

unsigned int : 4个字节(固定)

float: 4个字节(固定)

double: 8个字节(固定)

long: 4个字节

unsigned long: 4个字节(变化*,其实就是寻址控件的地址长度数值)

long long: 8个字节(固定)


64位操作系统

char :1个字节(固定)

*(即指针变量): 8个字节

short int : 2个字节(固定)

int: 4个字节(固定)

unsigned int : 4个字节(固定)

float: 4个字节(固定)

double: 8个字节(固定)

long: 8个字节

unsigned long: 8个字节(变化*其实就是寻址控件的地址长度数值)

long long: 8个字节(固定)

第一个指针数组10个指针:8*10=80

第二个数组指针,指向了一个存放10个char类型数据的数组 8

题目七 析构函数的调用顺序



main()函数中,第一句只用了new,调用了构造函数,没用delete,不会调用析构函数,内存泄露。第二句、第三句只是定义了指向不同对象的指针,不会产生对象,所以构造函数、析构函数都没调用,最后一句delete调用析构函数,因为基类A的析构函数不是虚函数,所以只调用A的析构函数,输出:~A(),如果A的析构函数加上virtual, 输出:~C()~B()~A(),与直接delete c输出一样。 析构函数声明为虚函数,这样析构时,先调用派生类的析构函数,再调用基类的析构函数,防止内存泄露。

题目八 浮点数精度问题

单7双16

题目九 关于头文件#include <stdio.h>和#include "stdio.h"

A中#include包括""和<>这两种情况,""实在用户工作目录下寻找(用户的工作目录是通过编译器指定的),<>是找系统标准库函数,通过系统环境变量指定系统库目录;

C,头文件中只能存放全局变量的声明,定义要放在.cpp文件中,如果把定义放在.h文件中会出现error LNK2005:  already defined in xxx.obj
fatal error LNK1169: one or more multiply defined symbols found
Error executing link.exe.这样的链接错误;

D,这个作为一个程序员应该具备的常识,要把这些东西放在不同的.h文件中。

题目十  MIT HAKMEM算法

这个算法本质上是求n的二进制表示中1的个数问题。f函数是一个斐波那契数列,f(7)=21,f(9)=55;分别有3个和5个。

算法详解参见这里

题目十一  舍入误差/十进制到二进制小数的误差

A 2的平方根是一个无限循环小数。

B 2^64<2^90<10^30

C十进制小数转换为二进制时,只有当小数点后位权是2的负次幂时才不会发生误差。十进制小数转化为二进制时规则是乘2取整,顺序排列。

题目十二  分解质因数/最小公倍数/最大公约数

合数概念:合数指自然数中除了能被1和本身整除外,还能被其他数(0除外)整除的数。与之相对的是质数,而1既不属于质数也不属于合数。最小的合数是4。其中,完全数相亲数是以它为基础的。

分解质因数:每个合数都可以写成几个质数相乘的形式,其中每个质数都是这个合数的因数,把一个合数用质因数相乘的形式表示出来,叫做分解质因数。如30=2×3×5 。分解质因数只针对合数。求一个数分解质因数,要从最小的质数除起,一直除到结果为质数为止。

C++代码

#include <iostream>
using namespace std;

void prime(int n)
{
    if(n<2) return;
    int m=n;
    for(int i=2;i*i<=n;i++)
    { 
        while(m%i==0)   // 整除,说明i是因数 循环是看该因数是否还可以整除
        {
            m=m/i;      //重新赋值并输出
            cout<<i;
            if(m!=1) cout<<"*";     //说明后面还有
        }
    }
    if(m!=1) cout<<m;      //本身也是质数
    cout<<endl;
    return;
}

int main()
{
    prime(10);
    prime(1);
    prime(2);
    prime(4);
    prime(9);
    return 0;
}

这是一个从小到大输出质因数的例子

 #include <iostream>
using namespace std;
void prime_low_to_high(int number_input,int prime_begin)
{
    if(number_input>=prime_begin)
    {
        while(number_input%prime_begin)  prime_begin++;
        cout<<prime_begin<<endl;
        prime_low_to_high(number_input/prime_begin,prime_begin);
    }
    return;
}

void prime_high_to_low(int number_input,int prime_begin)
{
    if(number_input>=prime_begin)
    {
        while(number_input%prime_begin)  prime_begin++;
        prime_low_to_high(number_input/prime_begin,prime_begin);
        cout<<prime_begin<<endl;

    }
    return;
}

int main()
{
    prime_low_to_high(1,2);
    cout<<endl;
    prime_low_to_high(2,2);
    cout<<endl;
    prime_low_to_high(18,2);
    cout<<endl;

    prime_high_to_low(2,2);
    cout<<endl;
    prime_high_to_low(18,2);
    cout<<endl;
    return 0;
}

求最大公约数的2种方法:辗转相除和辗转相减。

#include <iostream>
using namespace std;

//辗转相除法
int method_div(int a,int b)   //大数除小数,若余数为0,最大公约数为较小值。否则小数做被除数,余数做除数。
{
    if(a<b)
    {
        int temp=a;
        a=b;
        b=temp;
    }
    int div=a%b;
    while(div!=0)
    {
        a=b;
        b=div;
        div=a%b;
    }
    return b;

}

//相减法
int method_minus(int a, int b)
{
    while(a!=b)  //大数减去小数,如果差和小数相等,差即最大公约数。否则小数与差做差。
    {
        if(a>b)
            a-=b;
        else
            b-=a;
    }
    return b;
}

int main()
{
    //相除法
    cout<<method_div(36,24)<<endl;
    cout<<method_minus(36,24)<<endl;

    cout<<method_div(36,7)<<endl;
    cout<<method_minus(36,7)<<endl;

    return 0;
}

求最小公倍数:先求a和b的最大公约数c,则a和b的最小公倍数为a*b/c

猜你喜欢

转载自blog.csdn.net/qq_40123329/article/details/86484850