练习
1. 请简述什么大端存储和小端存储?
大端存储:先存储高位字节,后存储低位字节。字中的字节顺序和原序列的相同。
小端存储:先存储低位字节,后存储高位字节。字中的字节顺序和原序列的相反。
(计算机中的地址从低地址到高地址)。
2. 请简述gcc的分步编译?
预处理:展开头文件,替换宏,删除注释。
编译:检查语法的正确性,生成汇编文件。
汇编:把汇编文件转换为二进制文件。
链接:把二进制文件链接为可执行文件。(将多个相关的目标模块链接成完整的可执行文件。)
3. 请回答文件剪切、复制的指令,并说明/etc /usr /mnt分别表示什么意思?
剪切:mv
格式:mv 文件1 文件2 把文件1重命名为文件2
mv 文件 目录 把文件剪切到目录中,目录必须存在
mv 目录1 目录2 把目录1重命名为目录2
复制:cp
格式:cp 文件1 文件2 把文件1拷贝到文件2
cp 文件 目录 把文件拷贝到目录,目录必须存在
cp 目录1 目录2 -r 把目录拷贝到目录
/etc :存放系统的所有配置文件,例如:passwd存放用户账户信息,hostname存放主机名等。
/usr :用于存放用户安装的软件和文件。
/mnt :通常用于作为被挂载的文件系统的挂载点。
4. 请问以下代码的输出结果是?
unsigned int i;
for(i=5;i>=0;i--)
{
printf(“hello\n”);
}
一直输出hello。(打印6次hello后,因为 i 是无符号数,执行 i-- 后变成最大值,再依次执行,没有符合跳出循环的条件。)
5. 请回答以下问题
void main() {
int a=100;
char c;
c=(char)++a;
printf("c=%d a=%d\n",c,a);
char d=4;
short e;
e=(++d)++;
printf("d=%d e=%d\n",d,e);
}
c=101,a=101;(char是一字节,最大可以取到127,++a之后a变成了101,再强转为char型,在0~127之间,字符和数字是相通的,区别在于要输出的时候以哪种形式输出。这里 c 和 a 都是以十进制输出,所以都是101。)
d=6,e=5;(括号得优先级最高,先执行括号里面的,得d=5,然后先运算再自增,把5赋值给e,d再自增)
6. 设有以下语句:int a=3,b=6,c; c=a^b<<2; 则c的二进制值是。
c的二进制是:00000000 00000000 00000000 00011011
(c=a^b<<2,运算的优先级是 << 、^ 、= ,6的二进制是 00000000 00000000 00000000 00000110,左移两位变为 00000000 00000000 00000000 00011000,再与3的二进制 00000000 00000000 00000000 00000011异或得 00000000 00000000 00000000 00011011)
7. 请回答以下程序
#include "stdio.h"
void main() {
int a=3;
a+=3!=3;
a*=++a+a;
printf("a=%d\n",a);
}
a=32。(a+=3!=3,运算优先级是 3!=3 这个表达式值为0,再算a+=0 得 a 得值为3,a*=++a+a,先对a自增,a的值变为4,再算 a+a 值为8 ,最后算a*=8 得32。)
8. 输入年月日,使用switch编程实现计算这是这一年的第几天?
Eg:输入:2024 4 1
输出:这是这一年的第92天
#include <stdio.h>
//宏定义各个月的天数
#define MONTH_1 31
#define MONTH_2 28
#define MONTH_3 31
#define MONTH_4 30
#define MONTH_5 31
#define MONTH_6 30
#define MONTH_7 31
#define MONTH_8 31
#define MONTH_9 30
#define MONTH_10 31
#define MONTH_11 30
#define MONTH_12 31
int main() {
int year,month,day;
printf("please input year month day:\n");
scanf("%d %d %d",&year,&month,&day);
//判断年份是否有误
if(year<1)
{
printf("enter year error!\n");
return -1;
}
//判断是闰年还是平年
int leap=0;//leap为0是平年,为1是闰年(当成平年闰年的标志位,也可以作为平年闰年时,2月份要加的天数。)
if(year%4==0 && year%100!=0 || year%400==0)
{
leap=1;
}
//判断月份是否有误
if(month<1 || month>12)
{
printf("enter month error!\n");
return -1;
}
//判断天数是否有误,1 3 5 7 8 10 12月有31天
if(month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12)
{
if(day<1 || day>31)
{
printf("enter day error!\n");
return -1;
}
}
//4 6 9 11月有30天
if(month==4 || month==6 || month==9 || month==11)
{
if(day<1 || day>30)
{
printf("enter day error!\n");
return -1;
}
}
//2月,平年28天,闰年29天
if(month==2)
{
if(leap==1)//闰年
{
if(day<1 || day>29)
{
printf("enter day error!\n");
return -1;
}
}else if(leap==0)//平年
{
if(day<1 || day>28)
{
printf("enter day error!\n");
return -1;
}
}
}
int days=0;
switch(month)
{
case 12:
days+=MONTH_11;
case 11:
days+=MONTH_10;
case 10:
days+=MONTH_9;
case 9:
days+=MONTH_8;
case 8:
days+=MONTH_7;
case 7:
days+=MONTH_6;
case 6:
days+=MONTH_5;
case 5:
days+=MONTH_4;
case 4:
days+=MONTH_3;
case 3:
days+=MONTH_2+leap;
case 2:
days+=MONTH_1;
case 1:
days+=day;
break;
}
printf("that's %d days of the year\n",days);
return 0;
}
9. 简述以下程序有什么问题
int x=5;
while(x>0);
x--;
死循环,没有结束条件。while()后面加了分号,导致 x-- 不包含在 while 循环中,最终 while 没有跳出循环的条件,从而 while 一直执行下去。
10. 请简述以下程序的区别
#include "stdio.h" 与 #include <stdio.h> :
#include "stdio.h" :在调用某个函数时,先在用户自己编写的文件中查找,如果找不到再到库文件里取找。(自己编写的文件都要加双引号 “ ”)。
#include <stdio.h> :是直接到库文件里去找。
11. 请简述以下程序的
int n=0;
while(n=1)
n++;
//while循环执行次数是
死循环,while一直执行下去。( while() 括号里面重新给 n 赋值了,赋值后,执行n++,导致n 不存在跳出循环得值。)
12. 请编程实现:写一个“标准”宏 MIN ,这个宏输入两个参数并返回较小的一个。
#include <stdio.h>
#define MIN(a,b) (a<b?a:b)
int main() {
int a,b;
scanf("%d%d",&a,&b);
printf("%d\n",MIN(a,b));
return 0;
}
13. 请编程实现输出起始值到终止值之间的素数。
#include <stdio.h>
#include <math.h>
//c语言形式交换两个数(这里没用c++的引用)
void swap(int *star,int *end) {
int tmp;
tmp=*star;
*star=*end;
*end=tmp;
}
int main() {
int star,end;
printf("please input star and end:");
scanf("%d%d",&star,&end);
if(star>end)//如果起始值大于终止值,则交换
{
swap(&star,&end);
}
int i,j;
for(i=star;i<=end;i++)
{
int flag=0;//设置标志,flag==0是素数,flag!=0不是素数
for(j=2;j<=sqrt(i);j++)
{
if(i%j==0)
{
flag=1;
}
}
if(0==flag && 1!=i)//1不是素数
{
printf("%d\n",i);
}
}
return 0;
}
14. 请编程实现输出起始值到终止值之间的完美数。
#include <stdio.h>
void swap(int *star,int *end) {
int tmp;
tmp=*star;
*star=*end;
*end=tmp;
}
//请编程实现输出起始值到终止值之间的完美数。
int main() {
int star,end;
printf("please input star and end:\n");
scanf("%d%d",&star,&end);
if(star>end)//如果star大于end,就交换这两个数
{
swap(&star,&end);
}
int i,j,sum=0;
for(i=star;i<=end;i++)//i可以充当star到end之间的每一个数
{
sum=0;//防止下次从外层循环进入内层循环时,受内层循环上次所改变的num值的影响
for(j=1;j<i;j++)
{
if(i%j==0)
{
sum+=j;
}
}
if(sum==i)
{
printf("%d\n",i);
}
}
return 0;
}
作业之外(请编程实现输出起始值到终止值之间的回文数。)
#include <stdio.h>
//交换两个数
void swap(int *star,int *end) {
int tmp;
tmp=*star;
*star=*end;
*end=tmp;
}
int main() {
int star,end;//star和end分别为起始值和终止值
printf("please input star and end:");
scanf("%d %d",&star,&end);
if(star>end)//如果star大于end,则交换
{
swap(&star,&end);
}
int i,a,b,c=0;//i用来遍历,并代表star到end之间的每一个值。
for(i=star;i<=end;i++)
{
b=i;//b先存储一下一次循环中i的值,因为在内层循环中需要改变i的值,这里用b来代替i的改变
c=0;//内层循环中改变了c的值,再次从外层循环的进入的时候,需要重新初始化,防止上次循环改变的值,对本次循环有影响
do{
a=b%10;//a用来取输入的数的每一位
c=c*10+a;//c是把a取出来的每一位按逆序排回去
b=b/10;//b辅助a取输入的数的每一位
}while(b);
if(c==i)//判断重新组合的值是否与原本的值相等
{
printf("%d\n",i);
}
}
return 0;
}
15. 请编程实现图形打印。
_F
__FD
___FED
____FEDC
_____FEDCB
______FEDCBA
#include <stdio.h>
int main() {
int i,j;
for(i=0;i<=5;i++)//外层循环控制输出的行数,内层循环控制每行输出的个数即每行几列
{
for(j=0;j<=i;j++)
{
printf("_");
}
for(j=0;j<=i;j++)
{
printf("%c",'F'-j);
}
printf("\n");
}
return 0;
}
16. 循环输入10个成绩,请计算最大值,最小值。
方法1:(使用数组把输入的数存起来,假设一开始,最大和最小的数均为下标为0的数,从下标为1的开始往后遍历,依次和最大最小的数对比,并每次对比完后后面的数比最近一次记录的最大值的数大或比最小值的数小,则重新记录最大值的小标和最小值的下标。)
#include <stdio.h>
int main() {
int arr[10]={0};
int i;
printf("please input 10 number:\n");
for(i=0;i<10;i++)
{
scanf("%d",&arr[i]);
}
int min=0,max=0;//假设一开始数组下标为0的数为最大值或最小值
for(i=1;i<10;i++)
{
if(arr[max]<arr[i])//依次往后面遍历,若后面的数比数组下标为max的数要大,则重新记录较大的值的下标
{
max=i;//重新记录较大值的下标
}
if(arr[min]>arr[i])//依次往后面遍历,若后面的数比数组下标为min的数要小,则重新记录较小的值的下标
{
min=i;//重新记录较小值的下标
}
}
printf("max value=%d, min value=%d\n",arr[max],arr[min]);
return 0;
}
方法2:(不使用数组,在第二次输入数据后开始,每次与最大和最小的数对比,并把当前已经输入过的数的最大和最小值保存起来。)
#include <stdio.h>
int main() {
int num,max,min;//max用来存最大值,min用来存最小值
printf("please input 10 number:\n");
scanf("%d",&num);
max=num;//假设一开始输入的就是最大值
min=num;//假设一开始输入的就是最小值
int i;
for(i=0;i<9;i++)//再输入9个数
{
scanf("%d",&num);
if(num>=max)//每输入一次,就和原本的最大值比较,若大于之前的最大值,就用max重新记录一下最大值
{
max=num;//max为截止到目前为止输入的数中的最大值
}
if(num<=min)//每输入一次,就和原本的最小值比较,若小于之前的最小值,就用min重新记录一下最小值
{
min=num;//min为截止到目前为止输入的数中的最小值
}
}
printf("max value=%d, min value=%d\n",max,min);
return 0;
}
方法3:(单纯写着玩,实际做题的时候用前两种方法,推荐第一种。)(任何输入的数,按照递增或递减排序,最终两端的数就是最小和最大值。这里用的是大根堆排序。)
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct{
ElemType *elem;//存储元素的起始地址
int TableLen;//元素个数
}SSTable;
//初始化数组
void ST_Init(SSTable &ST,int len)
{
ST.TableLen=len;
ST.elem=(ElemType*)malloc(sizeof(ElemType)*ST.TableLen);//申请一块堆空间,当数组来使用
}
//打印
//void ST_print(SSTable ST)
//{
// int i;
// for(i=0;i<ST.TableLen;i++)
// {
// printf("%3d",ST.elem[i]);
// }
// printf("\n");
//}
//交换
void swap(int &a,int &b)
{
int tmp;
tmp=a;
a=b;
b=tmp;
}
//把某个子树调整为大根堆
void AdjustDown(ElemType A[],int k,int len)
{
int dad=k;//父亲的下标(下标从0开始)
int son=2*dad+1;//左孩子的下标
while(son<len)
{
if(son+1<len && A[son]<A[son+1])//如果左孩子小于右孩子
{
son++;//拿右孩子
}
if(A[son]>A[dad])
{
swap(A[son],A[dad]);
dad=son;//son重新作为dad,去判断下面的子树是否符合大根堆
son=2*dad+1;
}else{
break;
}
}
}
//堆排序
void HeapSort(ElemType A[],int len)
{
int i;
//就是把堆调整为大根堆
for(i=len/2-1;i>=0;i--)
{
AdjustDown(A,i,len);
}
swap(A[0],A[len-1]);//交换根部元素和最后一个元素
for(i=len-1;i>1;i--)//i代表的是剩余的无序数的数组的长度
{
AdjustDown(A,0,i);//调整剩余元素为大根堆
swap(A[0],A[i-1]);//交换根部元素和无序数的数组的最后一个元素
}
}
int main() {
SSTable ST;
ST_Init(ST,10);
int i;
for(i=0;i<10;i++)//循环输入十个数,并保存到数组中
{
scanf("%d",&ST.elem[i]);
}
//ST_print(ST);
HeapSort(ST.elem,10);//所有元素参与排序
//ST_print(ST);
printf("max value=%d, min value=%d\n",ST.elem[ST.TableLen-1],ST.elem[0]);
return 0;
}