牛客知识点整理

牛客题库练习整理


前言

提示:这里可以添加本文要记录的大概内容:

牛客c语言专项练习。


提示:以下是本篇文章正文内容,下面案例可供参考

一、专项练习c语言

1、练习3

1 以下表达式选择结果是()

int a = 0;

int b = (a=-1) ? 2:3;

int c = (a=0) ? 2:3;

A、b=2, c=2

B、b=3, c=3

C、b=2, c=3

D、b=3, c=2

解释:答案C。赋值语句的返回值为等号右侧的数值,所以a=0返回值为0。

整型——任何非零值(包括负数)转换为bool的结果是true。
浮点型——0.0转换为false,所有其他值转换为true
指针——(空指针转换为false,所有非空指针值转换为true)也是如此。

2、练习

#include <stdio.h>
#include <string.h>
static int a = 1;
void fun1(void) { a = 2; }
void fun2(void) { int a = 3; }
void fun3(void) { static int a = 4; }
int main() {
    printf("%d", a);
    fun1();
    printf("%d", a);
    fun2();
  printf("%d", a); 
 
  fun3( );
 
  printf("%d", a);
}

答案:1 2 2 2。

解释:第四次输出,定义了一个静态的局部变量,静态局部变量在函数调用结束后仍然存在,及它的内存空间不会被释放,但其他函数是不能引用它的,所以,两个静态变量虽然同名,但是并不是一样的东西,为2

2024年1月29日15:37:13 更新

这个题目再做还是有做错了。第二个和第三个、第四个都没做对。

3、练习

关于引用以下说法错误的是(E)。

A、引用必须初始化,指针可以不初始化

B、引用初始化以后不能被改变,而指针可以改变指向

C、不存在指向空值的引用,但是存在指向空值的指针

D、一个引用可以看作是某个变量的一个“别名”

E、引用传值,指针传地址

F、函数参数可以声明为引用或指针类型

解释:E:函数中,只有引用传地址,而指针也是传值的,只不过使用指针可以达到传址的效果。

4、练习

在VC6.0中,运行下面程序的输出结果是(C)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

#include <stdio.h>

#include <stdlib.h>

void MallocMem(char* pc) {

    pc = (char*) malloc (100);

    return;

}

int main() {

    char *str=NULL;

    MallocMem(str);

    strcpy(str,"hello ");

    strcat(str+2, "world");

    printf("%s",str);

    return 0;

}

A、hello world

B、程序编译错误

C、程序运行时崩溃

D、其他几项都不对

虽然答案是C,但是当时做题目看到strcat(str+2, "world");还是一愣一下,查了下strcat源码才了解为啥。

5、练习

#include <iostream>

#include<stdlib.h>
#include<stdio.h>

using namespace std;

int a;
int b;
int c;

void F0(){
    b = a * 2;
    printf("F0-a:%d\n", a);
    a = b;
}

void F1(){
    b = a * 2;
    printf("F1-a:%d\n", a);
    a = b;
}

void F2(){
    c = a + 1;
    printf("F2-a:%d\n", a);
    a = c;
}

int main(){
    F0();
    a = 5;
    // !!! Start F1(),F2() in parallel
    {
        F1();
        F2();
    }
    printf("%d\n", a);

    return 0;
}

//打印
//F0-a:0
//F1-a:5
//F2-a:10
//11

二、专项练习软件开发

1、练习1

下列代码的结果是

#include<stdio.h>
main() { 
    int a[5] = {1, 2, 3, 4, 5}; 
    int *ptr = (int *)(&a + 1); 
    printf("%d,%d", *(a + 1), *(ptr - 1)); 
}

A、3,5

B、2,4

C、2,5

D、3,4

解释:答案C。

数组名就是数组0号元素的地址。 
a = &a[0] 
&a 是指向一个有5个整型元素的数组的地址。 a是一维指针,&a相当于是二维指针。 &a+1 就是从a向后跳过一个完整的数组所占用的内存空间。 整型5个元素的数组占用 5*sizeof(int)=5*4=20,所以 &a+1应该从a向后跳20字节。正好指到a[4]的后面。ptr是int *, 减1就是向前跳4个字节,ptr-1正好指向a[4]

2、练习

4 以下表达式选择结果是()

int a = 0;

int b = (a=-1) ? 2:3;

int c = (a=0) ? 2:3;

A、b=2, c=2

B、b=3, c=3

C、b=2, c=3

D、b=3, c=2

解释:赋值语句的返回值为等号右侧的数值,所以a=0返回值为0。

整型——任何非零值(包括负数)转换为bool的结果是true。
浮点型——0.0转换为false,所有其他值转换为true
指针——(空指针转换为false,所有非空指针值转换为true)也是如此。

3、练习

a = i++赋值顺序

#include "stdlib.h"
#include "string.h"

int main()
{
    int i = 0;
    while(i++ < 4)
    {
        printf("%d\n",i);
    }

    int j = 0;
    while(j < 4)
    {
        int h = j++;
        printf("%d\n",h);
    }

    retunr 0;
}

//打印 1 2 3 4
//     0 1 2 3

赋值顺序不同:a=i++,先将i的值赋值给了a,然后才进行了i=i+1操作,最后把加1后的结果赋值给了i;但b=++i,先进行i=i+1操作,然后将加1后的结果先赋值给i,最后把i的值赋值给了b。这也就是i++和++i的运算区别。

4、练习

6、下列程序的运行结果是

int main()
{
    char ch[7] = {"65ab21"};
    int i, s=0;
    for(i = 0; ch[i] >= '0' && ch[i] <= '9'; i += 2)
        s = 10*s + ch[i] - '0';
    printf("%d\n", s);
    return 0;
}

A、12ba56

B、6521

C、6

D、62

2024年1月30日11:23:39

正确答案C,这次做做错了

5、练习

7、以下的变量定义语句中,合法的是(C)

A、byte a =128;

B、boolean b =null;

C、long c=123L;

D、float d = 0.9239;

解释:

double a = 0.9239(√)
double a = 0.9239d(√)
float a = 0.9239f(√)
float a = 0.9239(×)

2023年9月4日10:55:39

2024年1月30日14:50:41

为什么float a = 0.9239这种写法不对。我在程序中验证没问题啊

int main()
{
    float f = 1.23f;
    printf("%f\n", f);
    return 0;
}

6、练习

题目1

关于下面代码,哪些描述是错误的(ABCD)

1

2

3

4

std::vector<char> v{'1''2''3''4'};

// A

v.push_back('5');

// B

A、*v.end() == '4'

B、A和B位置v.capacity() 一定大于 v.size()

C、如果A位置v.size()与v.capacity()分别是4,4,那么B位置是5,5

D、如果A位置v.size()与v.capacity()分别是4,4,A位置&v[0]等于B位置的&v[0]

#include "stdlib.h"
#include "stdio.h"
#include <vector>

int main()
{
    std::vector<char> v{'1', '2', '3', '4'};

    printf("size:%d, capacity:%d\n",v.size(), v.capacity());
    printf("%p\n",&v[0]);

    v.push_back('5');
    printf("size:%d, capacity:%d\n",v.size(), v.capacity());

    printf("%p\n",&v[0]);

    for(int i = 0; i < v.size(); i++)
    {
        printf("%c ", v[i]);
    }

    return 0;
}


//size:4, capacity:4
//01131858
//size:5, capacity:8
//01131868
//1 2 3 4 5

这次capacity()也搞懂啦

2023年11月21日10:20:56 又不会了 -_-!

7、练习

2023年10月27日15:29:36

7.下列表达式中,不合法的是(AD)
已知:double d = 3.2; int n = 3;

A、d<<2;

B、d/n

C、!d && (n-3)

D、(d-0.2)|n

正确答案:AD

参考答案:AD 浮点数和位运算:所有的位运算都不能直接操作浮点数,这就是A和D错的原因,但是,我们可以间接对浮点数进行位运算,例如,将float数据,取地址(&)强行转化为整型(int等)指针后,再取值(*)后赋值给整型变量(int等),然后就能对该变量进行位运算了。 【注】对浮点数进行位运算,一般没什么意义,因为浮点数的存储结构分三部分,进行过位运算后,所得结果跟原始浮点数没多大关系。 B.d/n:在运算前,系统会自动把两个操作数转化为精度较高的那个数据类型,这里会自动将n转化为double类型,然后在进行运算; C.!d&&(n-3):逻辑运算符非(!)、与(&&)、或(||),操作数可以是任何基本数据类型,因此此表达式合法,可以正常运行。

位运算包括:

含义

Pascal语言

C/C++语言

Java

Php

按位与

a and b

a & b

a & b

a & b

按位或

a or b

a | b

a | b

a | b

按位异或

a xor b

a ^ b

a ^ b

a ^ b

按位取反

not a

~a

~a

~a

左移

a shl b

a <<b

a <<b

a << b

带符号右移

a shr b

a >> b

a >> b

a >> b

无符号右移

/

/

a>>> b

/

三、volatile

关于C语言中volatile关键字,下面的说法哪一个是错误的?  B

A、编译器会禁止对volatile修饰的变量进行读写优化

B、用volatile修饰的变量,读取速度会更快

C、每一次读取volatile修饰的变量都会从内存中读取

解释:

使用volatile关键字声明的变量,系统总是重新从它所在的内存中读取数据,即使它前面的指令刚刚从该处读取过数据,而且读取的数据立刻被保存;相反,若没有使用volatile,编译器可能会做优化处理,可能暂时使用寄存器中的值,而如果该变量由别的程序更新了的话,将会出现不一致的现象!!

总结起来就是:

1. 编译器会禁止对 volatile 修饰的变量做读写优化,A 正确;

2. 每次使用该变量时,系统都会重新从它所在内存中读取数据,C 正确;

3. 这相对于做了读取优化的变量来说,速度当然是慢了一些啦, B 错误。

四、柔型数组

1、对于 32 位机器,则下面代码输出结果为(B)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

#include<iostream>

#include<string>

using namespace std;

typedef struct data_ {

    int a[10];

} data_t;

typedef struct descriptor_ {

    data_t* ptr;

    char data[0];

} desc_t;

int main() {

    cout << sizeof(desc_t) << endl;

    return 0;

}

A、40

B、4

C、8

D、0

解释:这个题目就涉及到柔型数组,

为什么采用data[0]这种写法:

在结构中,data数组的真实地址紧随结构体MyData之后,即,如果给这个结构体分配的内容大于这个结构体实际大小,后面多余的部分就是这个data的内容,这种声明方法可以实现C语言里的数组扩展

实际用时采取这样:struct MyData *p = (struct MyData *)malloc(sizeof(struct MyData )+strlen(str))

这样就可以通过p->data 来操作这个str。

五、整型提升

有如下程序段:

1

2

3

4

5

6

7

#include <stdio.h>

int main() {

    char ch = -1;

    printf(" %02x, %02x", ch, (unsigned char)ch);

    return 0;

}

则输出:答案:C。

A、-1,-1

B、ff,ff

C、ffffffff,ff

D、ff,ffffffff

解释:

这是一道关于符号扩展的问题。

短数据类型扩展为长数据类型:①要扩展的数据类型为有符号类型,用短数据的符号位填充长数据多出来的高字节 ,-1 (11111111)扩展为int(方便转换为十六进制)即(符号位是1)11111111 11111111 11111111 11111111(ffffffff)②要扩展的数据类型为无符号的(unsigned char) ,用0来填充长数据类型的高字节,此时-1在内存的二进制存储(11111111 )扩展为int即00000000 00000000 00000000 11111111(ff)。

题目链接:有如下程序段,则输出?_迅雷笔试题_牛客网

2024年1月30日15:08:03

做错了,我做的是0x81和0xff。看了解释我都没搞懂,虽然用0x输出, 就一定要转成32位的吗?也许是吧,等于是强制转换了?

现在来看,我整理的关于C语言的题目也太少了吧。现在上面的很多题目我都做错了。

未完待续...


总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值