admin管理员组

文章数量:1658428

07-29 每日一练

1.Linux系统应用在哪些领域

  1. Linux作为企业级服务器的应用
  2. 嵌入式Linux系统应用领域
  3. 个人桌面Linux应用领域
  4. 修改:电子政务应用领域

2.VM虚拟机网络模式有NAT、主机、桥接,有什么区别

  • 桥接模式:虚拟网络和主机网络处于对等地位,拥有自己的IP地址。
  • NAT模式:虚拟系统通过主机所在网络访问公网,没有独立IP地址。
  • 主机模式:虚拟系统和真实网络相隔离,虚拟机仅能与主机户型访问,或访问同主机的其他主机模式虚拟机。默认情况无法连接Internet。

3.VM虚拟机快照功能有什么用,怎么用

  • 保存虚拟机的多个状态,起到备份恢复的作用
  • 拍摄快照:虚拟机选项卡->快照->拍摄快照
  • 快照恢复:虚拟机选项卡->快照->恢复到快照

4.VM虚拟机和win文件共享有哪几种方式

  • 方法1:添加共享文件
  • 方法2:安装VMware tool,通过拖拽方式移动文件
  • 方法3:通过xftp共享文件

—————————————————————————————————————————————————

07-30 每日一练

1.在/tmp/目录下创建test.txt文件,内容为: Hello,World! ,用一个命令写出来。

echo “Hello, World” > /tmp/test.txt

2.给test.txt文件除所有者之外增加执行权限,最终以数字写出文件的权限。

  • 查看权限:ls -l | grep test.txt
  • 对除所有者增加执行权限:chmod g+x,o+x test.txt
  • 以数字写出文件的权限:675

3.查找linux系统下以config结尾,并备份到/data/backup/目录下。

find / -name *config -exec cp {} /data/backup \

4.创建 test.txt所属的用户为root,组为abc,请将test.txt使拥有者为abc,组为root,写出命令。

chown abc.root test.txt

5.如何查看文件内容,命令有哪些?查看文件第1行到3行,查看文件最后一行。

  • 查看文件的内容:cat test.txt,head test.txt,tail test.txt,vim test.txt, more test.txt,less test.txt
  • 查看文件的第一行到第三行:head -3 test.txt
  • 查看文件的最后一行:tail -1 test.txt

6.查看linux服务器IP的命令

ip addr
ifconfig
netstat -tnlp

7.将普通用户test加入root组的命令是

  • sudo -s
  • visudo
  • 在打开的配置文件中,找到root ALL=(ALL:ALL) ALL,在下面添加test ALL=(ALL:ALL) ALL

—————————————————————————————————————————————————

07-31 每日一练

1.何谓文件?

  • Linux奉行一切皆文件,文件时一系列可读写的数据块。

2.何谓文本文件?何谓二进制文件?

  • 文本文件:文本文件是指以ASCII码方式(也称文本方式)存储的文件,其内容可以直接被读取到。文本文件中除了存储文件有效字符信息(包括能用ASCII码字符表示的回车、换行等信息)外,不能存储其他任何信息。文本文件属于普通文件。
  • 二进制文件:二进制文件是包含在 ASCII 及扩展 ASCII字符中编写的数据或程序指令的文件。二进制文件和文本文件的编码方式不同,二进制文件与文本文件同属于普通文件。

3.何谓字符编码?对于中文来说,GBK和UTF-8一般各占几个字节?

  • 字符编码是指是把字符集中的字符编码为指定集合中某一对象,以便文本在计算机中存储和通过通信网络的传递。
  • 对中文来说,GBK占2字节,UTF-8占3字节。

4.对于编译性语言,源文件到可执行文件做了哪些处理?

  • 预处理、编译、链接

5.综合上述问题,请解释:

  1. 何谓编译器?
    将源代码(通常为高级语言)到能直接被计算机或虚拟机执行的目标代码(通常为低级语言或机器语言)的程序。

  2. 编译器究竟做了哪些事?
    词法分析、语法分析、语义分析、中间代码生成、中间代码优化、目标代码生成、目标代码优化

  3. 如何设计一门语言?
    (1)设计语言的特性。
    (2)定义语言的单词、语法和语义。
    (3)实现编译器或者解释器将程序翻译为计算机底层表示。
    (4)生成计算机程序的二进制存储格式。
    (5)完善语言的运行时环境和标准库。
    (6)对(5)进行引申

  4. 何谓链接器?
    将一个或多个由编译器或汇编器生成的目标文件外加库链接为一个可执行文件的程序。

  5. 何谓解释器?
    能够把高级编程语言一行一行直接转译运行的程序。

  6. 所谓编译型语言和解释型语言的区别?
    编译型语言,在程序执行之前,有一个单独的编译过程,将程序翻译成机器语言,以后执行这个程序的时候,就不用再进行翻译了。

    解释型语言,是在运行的时候将程序翻译成机器语言,所以运行速度相对于编译型语言要慢。

  7. 前一个问题的本质是_______的区别,为什么?
    编译。编译型语言的编译和执行分开,解释型语言执行的时候才翻译。

—————————————————————————————————————————————————

08-03 每日一练

1、什么是大小端字节序?

  • 字节序是大于一个字节类型的数据在内存中的存放顺序
  • 大端字节序:高位字节排放在内存的低地址段,低位字节配方在内存的高地址段。
  • 小端字节序:高位字节排放在内存的高地址段,低位字节配方在内存的低地址段。

2、如何通过语言判断字节序,请用目前的知识点(变量+运算符+输出函数)判断大小端。

  • 一字节表示的数范围为0-2^8,即2位十六进制数,0x12345678占4字节,即一个整形大小。

  • 联合类型中的几个变量公用一个内存位置,对union型成员的存取都是相对于该联合体基地址的偏移量为0处开始,也就是联合体的访问不论对哪个变量的存取都是从union的首地址开始的。通过检测第一个字节存放的数据即可判断大小端。

  • 代码:

    #include <stdio.h>
    union{
    char ch;
    int i;
    }un;
    
    int main(){
    un.i = 0x12345678;
    if(un.ch == 0x12){
    printf("big endian\n");
    }else
    {
    printf("small endain\n");
    }
    return 0;
    }
    

—————————————————————————————————————————————————

08-04 每日一练

将源文件变成可执行文件称为编译过程,请问:

  1. 对编译效率影响最大的是哪个步骤?

    推导C++的模板

  2. 如何提升编译效率?既编译效率的优化。
    (1)在头文件中使用前置声明,而不是直接包含头文件。
    (2)使用Pimpl模式
    (3)高度模块化
    (4)删除冗余的头文件
    (5)预编译头文件(PCH)

引自云梦之殇的新浪博客:http://blog.sina/s/blog_6cf921f301014gbc.html

—————————————————————————————————————————————————

08-05 每日一练

1.什么是初级程序员?

  • 效率较低的,低产的程序员

2.如何进阶为高级程序员?

  • 做更“注重实效”的程序员

3.非专业性知识上,初级程序员需要具备哪些特质,才能进阶为高级程序员呢?

  • 喜爱试验各种事物
  • 好奇,喜欢提问
  • 做批判的思考者
  • 有现实感,会设法理解面临的每个问题的内在本质
  • 多才多艺,尽力熟悉广泛的技术和环境
  • 关心自己的技艺,思考自己的工作

4.这些特质现阶段你个人具备了多少呢?

  • 具有现实感,做批判的思考者

—————————————————————————————————————————————————

08-07 每日一练

1.程序是什么?

  • 程序是一组计算机能识别和执行的指令,运行于电子计算机上,满足人们某种需求的信息化工具。

2.程序由哪些部分组成?

  • 数据结构+算法

3.可执行文件运行起来叫做进程,运行这个操作做了哪些事?

  1. 申请空白PCB(过程控制块)
  2. 为新工序分配资源。
  3. 初始化PCB
  4. 将新进程插入就绪队列

4.你觉得程序员是怎么分级的?

  • Level 1,读写——他们了解设置Web服务器的方法,在普通情况下能够通过配置方式获取工作所需要的东西。他们有使用文本编辑器和文件系统的基础知识,还拥有移动和操作文件的能力,如ZIP和FTP。也能在结构中使用抽象符号、解析方式以及系统技能。
  • Level 2,脚本——能够编写线性脚本告诉电脑要做什么,能够学习和使用自己的符号。如果有足够的时间和书面指导,他们可以使用bash或VB编写一些简单脚本,为自己做些实用的事情。
  • Level 3,管理员——这些人了解库和API,并有能力学习更多。他们知道不管使用什么脚本语言都需要连接库。如果他们遇到问题,可以通过阅读使用手册或是在网上搜索库来解决。在工作中他能够发现或是开发自己的符号(使用struct编写函数或是声明)。大多数系统程序员都处在这个等级阶段,Excel的初级宏系统用户也同样处在这个阶段。
  • Level 4,高级实践者——刚开始接触耦合性与内核,他们能编写自己的对象化脚本(有公有/私有成员和方法)。这些人能玩转技巧,了解库和构建类。如果不使用类,他们也能够创建自己的模块或是代码文件。高级脚本用户可远不止这样,有一些Excel技巧经验丰富的股票经纪人,他们使用自己VBA作为基础代码,而没有意识到自己处于这个级别。
  • Level 5,掌握多种技能——一旦上升到这个级别,将会遇到各种各样的麻烦。常见编程下一阶段就是能够使用多重框架。这些人可以编写C#,也知道如何创建表格和编写SQL语句;可以编写C,同时也会使用JavaScript和HTML。这两个技能并不代表他们就是大师,只是要学会在理解同一个问题上,需要通过多种不同的方式来找寻答案。
  • Level 6,初级构架师——这阶段的人才算是真正的从事编程工作。他们每天的工作就是要深入了解库和API。并不要求他们必须记住这些,但要了解用不同的模式去实现自己的目标。想要在Win32中绘制?可能需要一些GDI资源句柄,他们知道句柄是在系统表某处的一个UInt32 hash——常见的Win32范例。想在自己的库中添加jQuery?新库里有很多格式,他们应该知道怎么做并且能解释其工作方式。与此同时,也要开始学习如何重构自己的代码并突显亮点,增强其代码的质量,慢慢地你会理解。
  • Level 7,资深构架师——他们的时间是用来创建自己的API、平台或是库。也许这是一个大项目的必需品,也许只是他们个人想把自己的学识推广出去。他们开发的系统为用户解决实际问题,所面对的受众群是Level5程序员。在这个阶段需要深入OOAD,模板和实践。我们大多数人在刚开始都会搞得一团糟,不能理解怎么用更加简单的方法将复杂事情简易化。这个阶段需要历经很长时间,需要不断修正错误,开发高质量的系统并创建更复杂、灵活性高的库。当他们从外面接受几个月的特定培训回来,肯定希望团队其他人都能理解他做了什么。
  • Level 8,诠释者——在某些时候,希望这些人能意识到大量复杂信息投入结构和构架中可以更好地形容特定域的语言,其受众群体是Level4程序员。代码的复杂性增大,就能减少代码的数量,DSL开放可以将代码展示到各种地方。总之,他们将成为程序员使用脚本语言方面的作家。通过易于使用的脚本和导向将他们的系统开放给初学者。可以分别学习这些技能,但大多数情况是在复杂的结构后,最终走向DSL的道路。很快就能看到最初规模:利用自己编写的DSL能够很好的理解问题。
  • Level 9,函数式编程——慢慢接近奖金,他们要开始学习如何函数式编程。其受众群是Level3的程序员。函数式编程是必不可少的,帮助他们轻松地脱离DSL,并能够大幅度减少代码数量来解决问题,同时拥有较高的扩展性。某些功能语言在系统运行时可以hot–swap,慢慢就会感觉到已经接近先进水平。函数式编程是一切问题的答案,它可以减少Bug,提升开发效率,但代码也相对来说很难学。程序员的脑海里需要时刻记忆很多东西——他们必须要记住繁琐的复杂符号。但是,结根到底函数式编程只是道路上的一个阶段,就像OOAD一样。
  • Level 10,面向语言设计师——他们查看所有新创建的编程语言程序。惟一的区别是新语言应该做什么。他们了解如何开发面向对象语言,语言功能和脚本语言,知道每一个语言在何时何地的用途。其受众群是Level2程序员。他们对每一个项目都会问:“这个项目我们需要什么样的语言?”在项目完结后他们将会得到一个很好的工具,既解决了问题并易于理解还扩展了入门级程序员。大多数项目不需要面向语言设计师。
  • 上帝级别,计算机科学家——要么就是编程的顶峰要么就不存在,这个取决于自己的观点。这个就是科学规划,在里面有很多很酷的东西。任何一个人都是其受众群体。但重点不是在于做人们想要的东西,而是促进学术的发展。因为大多数编程能力水平都是基于人而言,人们居住在世界各地,也是必要条件之一。如何简单的在两国之间相互来往?

—————————————————————————————————————————————————

08-08 每日一练

1.static 修饰的变量存储在内存的什么区中

  • 静态域/静态存储区

https://wwwblogs/protected/p/6419217.html

2.简述下变量的作用范围,以及你们对变量的理解

  • 全局变量:在所有函数外部定义的变量(通常是在程序的头部),称为全局变量。全局变量的值在程序的整个生命周期内都是有效的。全局变量可以被任何函数访问。
  • 局部变量:在函数或一个代码块内部声明的变量,称为局部变量。它们只能被函数内部或者代码块内部的语句使用。

3.if 语句和三目运算符的的比较,简述各自的优缺点

  • If语句优点:
    1.更加灵活(三目运算符的两个结果类型必须一致);
    2.可以使用多重if-else语句结果数可大于2;
  • 三目运算符优点:
    1.写法简洁,可用于宏定义
    2.可以将条件表达式的值直接赋予某个变量

—————————————————————————————————————————————————

08-10 每日一练

typedef struct bb
{
    int id;   
    double weight;  
    float height; 
}BB;

typedef struct aa
{
    char name[2]; 
    int  id;
    short score; 
    short grade; 
    BB b; 
}AA;

这两个结构体 分别占用多大的内存,为什么?

  • BB占24字节,AA占40字节
  • char类型1字节 ,Int类型4字节,short类型2字节 ,float类型4字节,double类型8字节
  • 字节对齐:结构体每个成员相对于结构体首地址的偏移量是成员本身的整数倍,结构体的总大小为结构体最宽基本类型成员大小的整数倍。可以简化为将占内存最大的类型成员大小作为一个单位,在该单位中合并填充结构体所有的类型,填充过程中同样要求符合该单位内内存最大的类型成员大小作为一个单位。
  • 在BB结构体中,double是占用内存最大的成员,所以偏移量为8字节,因为int、double、float不能在8字节内合并,所以BB占用的空间为8+8+8=24字节。
  • 在AA结构体中,double是占用内存最大的成员,所以偏移量为8字节,因为两个char和int合并为8字节,两个short合并为8字节,BB单独占用24字节,所以AA占用的空间为8+8+24=40字节。

—————————————————————————————————————————————————

08-11 每日一练

1.用宏定义写出swap(x,y),即交换两数。

#define swap(x,y) y=x+y; x=y-x; y=y-x

2.写一个“标准”宏,这个宏输入两个参数并返回较小的一个

#define min(x,y) ((x)>(y)?(y):(x))

—————————————————————————————————————————————————

08-12 每日一练

某实验室,现有64瓶药水,其中一瓶会致死。现在你可以用小白鼠来测试药水。小老鼠在吃了有毒的药水后,需要3天才会死亡。现在你只有三天时间,请问最少需要多少只老鼠就可以找出有毒的药水。

  • 假设有n只小鼠,这n只小鼠共有2^n 种不同的组合,让这2^n种组合每个唯一对应一瓶药水,三天后哪种组合死了即哪瓶药水有毒。故n=log2 64=6只。

—————————————————————————————————————————————————

08-13 每日一练

你的公司有一个巨大的C++代码库,是多年来数十名乃至数百名工程师努力工作的成果。你发现需要对这些代码进行大规模的重构,比如从32位升级到64位,或是修改使用数据库事务的方式,或是因为需要升级C++编译器,语法和语义全部(又)变了。你的任务就是把代码调通了。你会怎么做?

  1. 明确需求
  2. 找出需要重构的代码段
  3. 分而治之地重构代码

—————————————————————————————————————————————————

08-15 每日一练

请问下图中哪个循环体运行效率更高?为什么?

for (i = 0 ; i < 100 ; i++){
	for (j = 0 ; j < 5 ; j++){
		Action();
	}
}

for (i = 0 ; i < 5 ; i++){
	for (j = 0 ; j < 100 ; j++){
		Action();
	}
}
  • 第二种效率更高,如果外循环比较大,则内存地址跳跃性比较大,cache命中率比较低,所以会慢点,不过也不是绝对的,可是概率上可能会慢。

—————————————————————————————————————————————————

08-17 每日一练

1.分析编译期错误,链接期错误,运行期错误

  • 编译器错误:源程序分析过程中发现有语法错误,给出提示信息。这是指在程序的编译过程中由编译程序识别或检查出来的错误,常称之为“语法错误”。诸如不符合规定的语句格式、对象说明与使用不一致、不正确的分隔符、不存在的标号、不正确的初始化数据、不恰当的循环嵌套等等。在编译期发现一个错误后,编译工作并不立即停止,而是尽可能多地找出源程序中的全部错误。
  • 链接期错误:连接程序在装配目标程序时发现的错误,通常由于函数名书写错误、缺少包含文件或包含文件的路径错误等原因引起的。
  • 运行期错误:可执行程序执行过程中发现的错误。如在计算过程中遇到了除数为零的错误、求一个负数的平方根等等。编译系统发现这类错误后如无特殊指示通常告知一些适当信息,然后立即停止程序的执行。当然,为阻止这类错误的出现,程序设计者可在程序中编入一些由自己来检查这类错误的程序段。

2.请分析代码中的变量储存在bss\data\stack等哪个段?

#include<stdio.h>
#include<string.h>
#include<stdlib.h> 
int z = 9; 
int a;
static int b =10; 
static int c; 
void swap(int* x,int* y) { 
int temp; 
temp=*x; 
*x=*y;
*y=temp;
} 
int main() { 
int x=4,y=5;
swap(&x,&y); 
printf(“x=%d,y=%d,z=%d,w=%d\n”,x,y,z,b); 
return 0;
} 
  • bss:用来存放程序中未初始化的全局变量的一块内存区域,属于静态内存分配。全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。包括变量a、c
  • data:用来存放程序中已初始化的全局变量的一块内存区域,属于静态内存分配,包括变量z、b
  • stack:堆栈,是用户存放程序临时创建的局部变量,包括变量x、y

—————————————————————————————————————————————————

08-18 每日一练

请设计一款加减乘除计算器,要求能输入小数,并对非数字的输入进行报警。同时编写代码规范整洁。

#include<stdio.h>
int main() { 
	float a,b,result; 
	char op;
	bool judge;
	int p;
	while(1){
		p = scanf("%f%c%f",&a,&op,&b);//p的值是成功赋值的变量个数
		switch( p ) {
			case 0:
				getchar();//清除掉残留在输入流的错误输入,如果不清除则第二次循环的scanf会读取残留的错误输入而不会读取屏幕输入,表现为无限重复死循环
				getchar();
				getchar();
				judge = false;
				break;
			case 1:
				getchar();
				getchar();
				judge = false;
				break;
			case 2:
				getchar();
				judge = false;
				break;
		}
		
	  	switch ( op ) {
	    	case '+': 
				result=a+b; 
				break;
	   	 	case '-': 
				result=a-b; 
				break;
   		 	case '*': 
				result=a*b; 
				break;
    		case '/': 
				if ( b==0 ) 
					judge = false; 
				else 
					result=a/b; 
					break;
    		default: 
				judge = false; 
				break;
  		}
	  	if (judge) 
		  	printf("%.2f\n",result); 
		else 
			printf("data erro\n");	
		printf("----------\n");
		judge = true;
	} 
}

—————————————————————————————————————————————————

08-19 每日一练

这是某位同学对昨天计算器的回答。请大家基于他的这种设计模式,优化异常输入报警这个功能,要求不允许程序报警导致异常,能正常执行之后的操作。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//res:用于储存接收到的文本
//head:用于储存动态编写的程序头
//tail:用于储存动态编写的程序尾
char res[1000];
char final[2000];
const char * head = "#include <stdio.h>\nint main(){\nprintf(\"\%f\\n\",(float)(";
const char* tail = "));return 0;}";
int i=1;
//这个程序就是你输入一个文本,然后用c语言写一个程序(head和tail负责补全程序),编译并执行。。
int main(){
    while(i){
        printf("请输入表达式!(别超过1000个字符)\n");
        scanf("%s",res);
        //按用户输入将程序文本补全,并写入dynam.c
        sprintf(final,"%s%s%s",head,res,tail);
        FILE *fpWrite=fopen("dynam.c","w");
        fprintf(fpWrite,"%s",final);
        fclose(fpWrite);
        //编译并执行,gcc会自动检测,输入不对劲肯定就执行不了
        system("gcc dynam.c -o trueCalcu");
        system("./trueCalcu");


        printf("您还要继续嘛?继续请输入1,退出请输入0:__\b\b");
        scanf("%d",&i);
    }
    return 0;
}

改进代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//res:用于储存接收到的文本
//head:用于储存动态编写的程序头
//tail:用于储存动态编写的程序尾
char res[1000];
char final[2000];
const char* head = "#include <stdio.h>\nint main(){\nprintf(\"\%f\\n\",(float)(";
const char* tail = "));return 0;}";
int i=1;
float a,b,result; 
char op;
bool judge;
int p;
//这个程序就是你输入一个文本,然后用c语言写一个程序(head和tail负责补全程序),编译并执行。。
int main(){
    while(i){
        
        //改动开始
        do{
        	printf("请输入表达式!(别超过1000个字符)\n");
	        p = scanf("%f%c%f",&a,&op,&b);//p的值是成功赋值的变量个数
			judge = true;
			switch( p ) {
				case 0:
					getchar();//清除掉残留在输入流的错误输入,如果不清除则第二次循环的scanf会读取残留的错误输入而不会读取屏幕输入,表现为无限重复死循环
					getchar();
					getchar();
					judge = false;
					printf("d\n");
					break;
				case 1:
					getchar();
					getchar();
					judge = false;
					printf("dd\n");
					break;
				case 2:
					getchar();
					judge = false;
					printf("ddd\n");
					break;
			}
			
		  	if(op!='+' && op!='-' && op!='*' && op!='/'){
		  		judge = false;
			}
		  	
		  	if (!judge){
		  		printf("data erro\n");		
			} 
			printf("----------\n");
		}while(!judge);
		//改动结束
	
	
		sprintf(res,"%.2f%c%.2f",a,op,b);
        //按用户输入将程序文本补全,并写入dynam.c
        sprintf(final,"%s%s%s",head,res,tail);
        FILE *fpWrite=fopen("dynam.c","w");
        fprintf(fpWrite,"%s",final);
        fclose(fpWrite);
        //编译并执行,gcc会自动检测,输入不对劲肯定就执行不了
        system("gcc dynam.c -o trueCalcu");
        system("./trueCalcu");


        printf("您还要继续嘛?继续请输入1,退出请输入0:__\b\b");
        scanf("%d",&i);
    }
    return 0;
}

—————————————————————————————————————————————————

08-20 每日一练

1.写出 float A 和“零值”比较的 if语句

Const float EPSINION=0.00001;
If((A>=EPSINION)&&(A<=EPSINION))
  • 不可以将浮点变量用‘==’或‘!=’与数字比较,应该设法转换成‘>=’或‘<=’此类形式。计算机在处理浮点数的时候是有误差的,所以判断两个浮点数是不是相同,是要判断是不是落在同一个区间里。这个区间就是【-EPSINION,EPSINION】EPSINION的值一般很小,为1e-6(与机器有关)。

2.以下代码有什么问题?该怎么改?

int main(){
char a;
char *str = &a;
strcpy(str,"how r u");
printf(str);
return 0;
}
  • 没有添加头文件。修改:在开始加上#include<stdio.h>和#include<string.h>
  • Str作为a字符的指针不能将字符串通过strcpy函数赋值给字符a。修改:将a的声明改为char a[50];
  • Printf格式错误,修改:应改成printf("%s",str);

—————————————————————————————————————————————————

08-21 每日一练

1.谈谈对数组的理解

  • 同一种类型数据的集合。其实数组就是一个容器。可以自动给数组中的元素从0开始编号,方便操作这些元素。

2.执行下面代码后,数组里存放的值是什么

  int m[5] = {1,2,3,4,5};
  int i = 2;
  int y = 10;
  m[i++] += y;  
  • {1,2,13,4,5}

—————————————————————————————————————————————————

08-22 每日一练

解释下下面的变量,什么是可变的,什么是const的

const char *p;			//*p不可变,p可变
const (char *) p;		//语法错误
char* const p;			//*p可以改变  p不能改变
(char*) const p;		//语法错误
const char* const p; 	//p和*p都不可以改变

—————————————————————————————————————————————————

08-24 每日一练

分别用demo测试一下这几个指针的区别

p++ 与 (p++) *p++与(*p)++

p++p自增
(p++)p自增
*p++p自增
(*p)++p指向的变量自增

—————————————————————————————————————————————————

08-25 每日一练

简述下 结构体 枚举 联合体 的共同点和区别

  • 共同点:都是C语言的一种构造型数据类型。
  • 不同点:
    (1)结构体总空间大小,等于各成员总长度,联合体空间等于最大成员占据的空间。
    (2)枚举元素是常量,只能在定义阶段赋值。

—————————————————————————————————————————————————

08-26 每日一练

有下面三个结构体,求 下面3个结构体的内存大小

typedef struct cc
{
    unsigned int a:2;   
    unsigned int b:1;;  
    unsigned int c:2;
}CC;

typedef struct bb
{
    int id;   
    double weight;  
    float height; 
}BB;

typedef struct aa
{ 
CC c; 
    char name[2]; 
    int  id;
    short score; 
    short grade; 
    BB b; 
}AA;

分别为:4,24,40

—————————————————————————————————————————————————

08-27 每日一练

不用库函数,如何最精简的将大写字母变成小写字母?如:‘A’变成‘a’

‘a’=‘A’+32

—————————————————————————————————————————————————

08-28 每日一练

1.main函数的参数和返回值有什么意义?

  • 参数
    (1)C语言规定main函数的参数只能有两个,为argc和argv,main函数的函数头可以写为:main (int argc,char *argv[])。
    (2)main函数的参数值是从操作系统命令行上获得的
    (3)argc参数表示了命令行中参数的个数(注意:文件名本身也算一个参数),argc的值是在输入命令行时由系统按实际参数的个数自动赋予的。

  • 返回值
    main 函数的返回值类型必须是 int ,这样返回值才能传递给程序的激活者(如操作系统),让操作系统判断程序的执行情况(是正常结束还是出现异常)。

2.调用main函数之前发生了什么?

  • 初始化全局变量

—————————————————————————————————————————————————

08-29 每日一练

数组越界有什么危害?怎么避免数组越界

  • 当出现越界时,由于无法得知被访问空间存储的内容及功能,所以会出现不可预知后果。可能程序崩溃,可能运算结果非预期,也可能完全没有影响。
  • 避免数组越界
    (1)检查传入参数的合法性。
    (2)在处理的时候,可以判断数组的大小,保证自己不要访问超过数组大小的元素,这样就不会出现数组越界异常了。
    (3)当处理数组越界时,打印出遍历数组的索引十分有帮助,这样我们就能够跟踪代码找到为什么索引达到了一个非法的值

—————————————————————————————————————————————————

08-31 每日一练

请画出Smart_Home的变量内存分布示意图,并优化两个结构体使得内存占用最少。

struct Owner{
unsigned char ID:3;
short Temp;
unsigned char Air:2;
}
  • 2+2+2=6B
  • AIR+Temp+ID
struct Smart_Home{
unsigned char Address[2];
unsigned char door:1;
struct Owner p;
unsigned char Room_ID:4;
unsigned char Light:3;
}
  • 2+2+6+2=12B
  • Address+door+Room+Light+Owner

本文标签: