Day2~Day5

C语言刷题(Day2~Day5)

​ 2023.03.26~2023.04.02


一、内容来源

1、题目来源
    ————————————————
	牛客网 刷题部分 C语言

二、疑惑知识点小结

Day2

1、C程序书写格式比较自由,一个语句可以分写在多行上。(比如说 while 语句,等可以分多行进行编写)
    
2、为什么 语句#include< stdlib.h >是正确的,而且程序编译速度比#include “stdlib.h”要快?
    答: include <file>  //在标准库及默认搜索目录中寻找将要 include 的文件 ;
		include "file" //先在当前目录中搜索文件,然后再到默认搜索目录中搜寻。
    
3、printf 函数的返回值为:函数返回输出的字符串的长度,但是不包括结束符‘\04、free 释放掉一个指针内容后,指针还会指向原来的那块地址,需要我们设置p = NULL;如果不手动设置 p = NULL,此时P就变成了野指针。
    1)野指针:表示的是保存了没有使用到的指针地址。
    
532位机中,无论是什么指针,它的长度都是四字节。
    
6、函数的默认值 函数的默认值不允许为局部变量 (什么讲究?)【】

7、new delete 与malloc free 的联系与区别 是什么?
    1)new会先调用operator new函数,申请足够的内存(通常底层使用malloc实现)。然后调用类型的
    构造函数,初始化成员变量,最后返回自定义类型指针。delete先调	用析构函数,然后调用operator 
    delete函数释放内存(通常底层使用free实现)
       malloc/free是库函数,只能动态的申请和释放内存,无法强制要求其做自定义类型对象构造和
       析构工作
    
8、内联函数有什么作用?
    1)可以把它作为一般的函数一样调用,但是由于内联函数在需要的时候,会像宏一样展开,所以执行速度
    确比一般函数的执行速度要快。当然,内联函数也有一定的局限性。就是函数中的执行代码不能太多了,
    如果,内联函数的函数体过大,一般的编译器会放弃内联方式,而采用普通的方式调用函数。(换句话说
    就是,你使用内联函数,只不过是     向编译器提出一个申请,编译器可以拒绝你的申请)这样,内联
    函数就和普通函数执行效率一样了
    2)当只有一个地方调用了内联函数时,编译器会在调用处将内联函数展开,这样就少了函数的跳转指令,
    栈的扩展指令,因此可能减小文件的大小
                                                                                                                                 

Day3

1、关于多态性的说法
	1)多态性是指同名函数对应多种不同的实现
	2)重载方式包含函数重载和运算符重载
	3)多态性表现为静态和动态两种方式

2、scanf ()函数中, %d 对应的参数是整数型地址, %c 对应参数为 char 型地址;如果输入地址有多个,
应该用逗号隔开

3、函数原型声明语句 :形式参数,只需要指定类型,名称可有可无

Day4

1、程序中自动转换是从位数少的转换为位数多的

2、指针变量若赋值一个字符串,则会得到这个字符串的首地址

3、联合体的大小为联合元素内最大元素的字节数

4、默认参数匹配时,按照靠前原则

		int  fun( int i = 1, intj = 2) {  return  (i + j); }

		则fun(3)的值为:5

5、二维数组定义规范:定义字符型数组时不允许直接使用“字符常量”的方式赋初值,C语言规定,二维数组定义时
不允许省略第二维的长度

Day5

三、错题记录

Day2

1.代码段char a[] = {'a','b','c'};char` `b[] = {“abc”``};

数组a和数组b占用的内存空间大小不一样。请问这句话的说法是正确的吗?

正确,大小不一样。因为数组b中 还有一个结束符 会占据一个字节

2.以下程序中,while循环的循环次数是()

int i=0;

while (i<10) { if(i<1) continue; if(i==5) break; i++;}

正确答案为:死循环,不能缺点给次数,因为i的初始值为0,当进入循环体中之后,if后面的条件 i<1 成立
之后,i不会加加,会一直循环 continue 语句

3.下面代码段的输出为() #define MOD(x,y) x%y int` `a = 13, b = 94;printf(“%d\n”``, MOD(b,a + 4));

正确输出为:7   需要注意的是宏定义只是简单的替换,不涉及运算符的计算

4.以下选项中,对基本类型相同的指针变量不能进行运算的运算符是()

A +
B -
C =
D ==

正确答案:A    因为两个相同类型的指针变量进行相加的话,很可能会出现指针越界的情况,所以不允许相加

5.下面代码的执行结果是() #include <stdio.h>

int` `main(void)

{ char` `*p[] = {“TENCENT”, “CAMPUS”, “RECRUITING”};

char` `**pp[] = {p + 2, p + 1, p};

``char ***ppp = pp;

printf("%s ", **++ppp);printf(“%s”, *++*++ppp);

return` `0;}

A CAMPUS RECRUITING
B RECRUITING CAMPUS
C CAMPUS CAMPUS
D RECRUITING RECRUITING
    

解析如下:

img
从题干当中,我们可以画出这样的一个图,这样就比较直观的看出了p,pp,ppp都指向哪里了,关键是最后两个printf语句。
(1)printf(“%s”,**++ppp);即,ppp当前所指向的位置,再往下移一个位置,即pp的位置2,而pp的位置2指向的是p的位置2,p的位置2指向的是CAMPUS,所以先输出CAMPUS

(2)printf(“%s”,++++ppp);这个语句等价于 printf(“%s”,++(++ppp));所以我们首先看,++ppp,第一个printf语句中ppp已经指向了pp的位置2,所以再往下移一个,指向了pp的位置3,而(*++ppp)则代表pp位置3所指向的内容,即p的位置1(pp的位置3指向的是p的位置1),在此基础上前面再加上一个++,则代表指针p在位置1的基础上再往下移动,即指针p的位置2,而p的位置2所指向的内容是CAMPUS,所以第二行输出的也是CAMPUS。
所以正确答案是:CAMPUS CAMPUS


Day3

1、下面3段程序代码的效果一样吗?

intb;(1)constinta = &b;(2)intconsta = &b;(3)int*``const a = &b;

A (2)=(3)
B (1)=(3)
C (1)=(2)
D 都不一样
E 都一样
    
    解析:
    const*的左边,则指针指向的变量的值不可直接通过指针改变(可以通过其他途径改变);*的右边,则
    指针的指向不可变。简记为"左定值,右定向"

2、下述程序的输出是 #include<stdio.h>

int main()
{
static` `char` `*s[] = {“black”, “white”, “pink”, “violet”}; char **ptr[] = {s+3, s+2, s+1, s}, ***p;
p = ptr; ++p;
printf(“%s”, **p+1); return 0``;
}

A ink  【√】
B pink
C white
D hite
    解析:如下图所示
    

在这里插入图片描述


Day4

1、extern “C” 的作用:

extern "C" 的作用是为了能够正确的实现 C++ 代码调用 C 语言代码。加上 extern "C" 后,会指示编译器这
部分代码按照 C 语言(而不是 C++)的方式进行编译。由于 C++ 支持函数重载,因此编译器编译函数的过程中
会将函数的参数类型也加到编译后的代码中,而不仅仅是函数名;而C语言并不支持函数重载,因此编译 C 语言
代码的函数时不会带上函数的参数类型,一般只包括函数名。 这个功能十分有用处,因为在 C++ 出现以前,很
多代码都是 C 语言写的,而且很底层的库也是 C 语言写的,为了更好的支持原来的 C 代码和已经写好的 
C 语言库,需要在 C++ 中尽可能的支持 C,而 extern "C" 就是其中的一个策略。

2、字符串数组 输出数组名 就是输出的一个字符串首地址,也就能直接输出其中的字符串了

3、fseek(fp, 0, SEEK_END); n = ftell(fp);

函数 ftell 用于得到文件位置指针当前位置相对于文件首的偏移字节数。

4、print()函数是一个类的常成员函数,它无返回值,下列表示中正确的是

A  const void print();
B  void const print();
C  void print() const;     【√】
D  void print(const);


解释:链接:https://www.nowcoder.com/questionTerminal/0f84a042640648e793bededd5956690d
来源:牛客网

常成员函数含义是通过该函数只能读取同一类中的数据成员的值,而不能修改它。
规则:
    1.常成员函数不能更新对象的数据成员
    2.当一个对象被声明为常对象,则不能调用该类中的非const成员函数
常成员函数格式:
    类型说明符 函数名(参数表)const;
    int GetX() const;     //声明常成员函数

5、使用C语言将一个1G字节的字符数组从头到尾全部设置为字’A’,在一台典型的当代PC上,需要花费的CPU时间的数量级最接近

解析:
执行1条语句约1ns即10-9次方秒,1G=1024M=1024*1024k=1024*1024*1024byte,每次赋值1byte都要执行
一次语句,故至少花费1024*1024*1024*10^-9=1.073741824s

Day5

1.C语言中,若有int a[5]={12,34,56,78,90},*p=a;则 *p++==13.

解析:
*p++ 相当于 *(p++) 是指针先加1,再进行解引用,相当于是地址指向34的位置,在进行解引用即为34.
    
    考点:操作符的优先级高低问题

2.下面代码的输出()

int main() {
int` `a[5] = {1, 2, 3, 4, 5}; intptr = (int)(&a + 1);
printf("%d, %d", *(a + 1), *(ptr - 1));
``return 0;
}

答案:25

解析:
a 为 int 型数组首地址,数组长度为 5,a + 1 表示 a[1] 的地址。
&a 可以理解为表示一个列数为 5int 型二维数组的首地址,那么 &a + 1 表示列为 5int 型二维数组
第 1 行首地址,然后转为 int 型指针赋值给 ptr,可以理解为 ptr 为 a[5] 的地址(可以这么理解,实际
不存在 a[5]),
ptr - 1 即为 a[4] 的地址

3.若有int c;,则while(c=getchar());是正确的 C 语句。请问这句话的说法是正确的吗?

c =getchar() 等号运算符的返回值是获得的字符。这样,当获得的字符不是\0时,则一直循环。
直到得到\0,退出循环

4.下面程序输出结果为()

class A {
};
int main() {
printf("%d\n", sizeof(class` `A)); return 0;
}

A 0
B 1
C 4
D 8

正确答案:B    空类的大小原本是0,但是为什么实际上是1,主要的一个中心思想是在强调:
任何相同类的不同对象应该拥有不同的地址。

5.空指针是指

A 所指向的空间位置未存放任何数据的指针
B 所指向的空间位置存放着数据0的指针
C 所指向的空间位置可用于存放任何类型数据的指针
D 所指向的空间位置就是地址0的指针
    
正确答案:D
    空指针是一个特殊的指针值。 空指针是指可以确保没有指向任何一个对象的指针。通常使用宏定义NULL来
    表示空指针常量值。NULL就代表系统的0地址单元 空指针确保它和任何非空指针进行比较都不会相等,因此
    经常作为函数发生异常时的返回值使用

6.以下代码编译有错误,哪个选项能解决编译错误?【???】

class A {
public:
int` `GetValue() const {
vv = 1; return vv;
} private: int vv;
};

A 改变成员变量"vv""mutable int vv"
B 改变成员函数"GetValue"的声明,以使其不是const的
C 都不能修复编译错误
D 都可以修复编译错误
    
正确答案:D
    普通成员函数后面加上 const 修饰,就是常函数。
	常函数中的 this 指针是常指针,不能在常函数中对成员变量进行修改,只能读取;
	如果想要在常函数中对成员变量进行修改,可以在成员变量前加上 mutable 关键字进行修饰;
	常函数可以被普通对象或者常对象调用,但是常对象只能调用常函数,常对象只能读成员

7.当调用函数时,实参是一个数组名,则向函数传送的是()【原题为多选,但是实际只有单选】

A 数组的长度
B 数组的首地址
C 数组每一个元素的地址
D 数组每个元素中的值
    
正确答案:B
   

8.开发C代码时,经常见到如下类型的结构体定义:

typedef struct list_t{struct` `list_t *next;struct list_t *prev;char` `data[0];}list_t; 最后一行char data[0];的作用是?

A 方便管理内存缓冲区
B 减少内存碎片化
C 标识结构体结束
D 没有作用
    正确答案:AB
    
    解析:看不懂char data[0];请去百度  柔性数组,它只能放在结构体末尾,是 申明一个长度为0的数组,
    就可以使得这个结构体是可变长的。对于编译器来说,此时长度为0的数组并不占用空间,因为数组名本身
    不占空间,它只是一个偏移量, 数组名这个符号本身代 表了一个不可修改的地址常量 (注意:数组名
    永远都不会是指针! ),但对于这个数组的大小,我们可以进行动态分配 请仔细理解后半部分,对于
    编译器而言,数组名仅仅是一个符号,它不会占用任何空间,它在结构体中,只是代表了一个偏移量,
    代表一个不可修改的地址常量!  对于0长数组的这个特点,很容易构造出变成结构体,如缓冲区,数据包
    等等: 注意:构造缓冲区就是方便管理内存缓冲区,减少内存碎片化,它的作用不是标志结构体结束,而是
    扩展 柔性数组是C99的扩展,简而言之就是一个在struct结构里的标识占位符(不占结构struct的空间)
  • 10
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值