C语言入门——编程题

1、输出不同整形数据类型在内存中占用多少字节?

首先明确整形数据有哪些:

(无符号)字符型:(unsigned)char

(无符号)短整型:(unsigned)short

(无符号)整形数据:(unsigned)int

(无符号)长整型数据:(unsigned)long

另:基本数据类型(四种):

整形:int short long

浮点型:float double

字符型:char

布尔型:bool(实际1bit)

#include<stdio.h>


int main()
{

	printf("sizeof(char)= %ld byte\r\n",sizeof(char));	
	printf("sizeof(short)= %ld byte\r\n",sizeof(short));	
	printf("sizeof(int)= %ld byte\r\n",sizeof(int));	
	printf("sizeof(long)= %ld byte\r\n",sizeof(long));	
	printf("sizeof(double)= %ld byte\r\n",sizeof(double));	
	printf("sizeof(float)= %ld byte\r\n",sizeof(float));	
	printf("sizeof(_Bool)= %ld byte\r\n",sizeof(_Bool));	
	


return 0;
}

运行结果:

 -------------------------------------------------------------------------------------------------------------------------------

2、我们处理的整数通常用十进制表示,在计算机内是以二进制补码形式存储,但通常二级制表示的整数比较长,为了便于在程序设计中理解和处理数据,通常采用八进制和十六进制,缩短了二进制补码表示的整数,但保持了二进制数表达的特点。请输出十进制整数“1234”对应的八进制和十六进制。

额外知识:

进制:十进制——逢十进一;八进制——逢八进一;十六进制——逢十六进一;二进制——逢二进一

二进制 源码:用第一位表示符号,其余位表示值

二进制 反码:正数的反码是其本身;负数的反码是符号位不变,其余位取反

二进制 补码:正数的补码是其本身;负数的补码是其反码+1

#include<stdio.h>


int main()
{

	int num = 1234;

	printf("十进制=%d\r\n",num);
	printf("八进制=%o\r\n",num);
	printf("十六进制=0x%x\r\n",num);
		


return 0;
}

运行结果:(没有二进制格式控制符)

 -------------------------------------------------------------------------------------------------------------------------------

3、十六进制转十进制:(0xabcdef)

#include<stdio.h>


int main()
{

	int num = 0xabcdef;

	printf("十进制=%d\r\n",num);
	printf("十六进制=0x%x\r\n",num);
		


return 0;
}

运行结果:

  -------------------------------------------------------------------------------------------------------------------------------

4、printf函数是有返回值的,求printf的返回值。

#include<stdio.h>


int main()
{


	printf("printf(A\\r\\n)的返回值为:%d\r\n",printf("A\r\n"));
	printf("printf(AB\\r\\n)的返回值为:%d\r\n",printf("AB\r\n"));
	printf("printf(ABC\\r\\n)的返回值为:%d\r\n",printf("ABC\r\n"));
		


return 0;
}

运行结果:(printf的返回值是:输出字符的个数) 

  -------------------------------------------------------------------------------------------------------------------------------

5、输入三科成绩,然后把三科成绩输出(数据范围:0~100)

#include<stdio.h>


int main()
{

	unsigned int grade[3]={0};
	for(int i=1;i<=3;)
	{
	
		printf("\r\n请输入科目%d成绩:",i);	
		scanf("%u",&grade[i-1]);
		if(grade[i-1] < 0 || grade[i-1] > 100)
		{
			printf("%d输入错误,请重新输入0~100之间的数据\r\n",grade[i-1]);
		}
		else i++;	
	}
	
	
	for(int i=0;i<sizeof(grade)/sizeof(int);)

		printf("科目%d成绩为:%d\r\n",++i,grade[i]);	


return 0;
}

输出结果:(不能输入字符数据,否则程序异常退出[未想出解决办法];成绩排序,后面学)

-------------------------------------------------------------------------------------------------------------------------------

6、依次输入一个学生的学号,以及三科成绩(C语言、数学、英语)成绩,在屏幕输出该学生学号及三科成绩(输出成绩需要四舍五入且保留两位小数;学号:20160344403)

#include<stdio.h>


int main()
{
	unsigned long number = 0;
	double grade[3]={0};
	for(int i=0;i<=3;)
	{
	
		switch(i)
		{
			case 0:
					printf("\r\n请输入学号:");
					scanf("%ld",&number);
//					continue;
					break;
			case 1:
					printf("\r\n请输入C语言成绩:");
					scanf("%lf",&grade[i-1]);
//					continue;
					break;
			case 2:
					printf("\r\n请输入数学成绩:");
					scanf("%lf",&grade[i-1]);
//					continue;
					break;
			case 3:
					printf("\r\n请输入英语成绩:");
					scanf("%lf",&grade[i-1]);
//					continue;
					break;
			default:
					printf("\r\ncode error...\r\n");
					break;
		}

		if(grade[i-1] >= 0 && grade[i-1] <= 100)
			{
				i++;
			}
		else
			printf("%lf输入错误,请重新输入0~100之间的数据\r\n",grade[i-1]);
	
	}
	

	printf("学号:%ld\r\nC语言         数  学         英  语  \r\n",number);
	for(int i=0;i<sizeof(grade)/sizeof(double);)
		printf("%.2lf          ",grade[i++]);	
		printf("\r\n");
return 0;
}

运行结果:

-------------------------------------------------------------------------------------------------------------------------------

7、输入一个字符,构造出一个一颗树🎄。

分析:会发现,其实后面的空格根本无需考虑,直接换行即可。

00000100000

00001110000

00011111000

00111111100

01111111110

11111111111

(代码写的有点花里胡哨,大半夜了,实在太困,就不详细写分析了。。。)

#include<stdio.h>


int main()
{

	char a = 0;
 printf("Please input a char:");
 scanf("%c",&a);
if(a != '\n' && a != ' ')
{
 printf("\r\nLet me make you a Christmas tree with:%c\r\n",a);

 for(int i=0;i<11;i++)
 {
 
	for(int j=0;j<((11-1)/2-i);j++)
	{
		printf(" ");
	
	}
	
 	for(int j=0;j<(2*i+1);j++)
	{
		if(i<=5)
		{
			printf("%c",a);	
		}
	}

	if(i>5)
	{
		for(int i=0;i<(11-3)/2;i++)
		printf(" ");
		printf("|");
		printf(" ");
		printf("|");
	}

	printf("\r\n");
 }

}
else
	{printf("\r\n请输入可见字符\r\n");}

	return 0;
}

输出结果:

-------------------------------------------------------------------------------------------------------------------------------

8、输出ASCII表(常用)

#include<stdio.h>

int main()
{
	printf("--DEC--HEX--ASCII---DEC--HEX--ASCII----table\r\n");

	for(int i=48;i<123;i++)
	{
		if(i%2)
		printf("    | %.3d | %x | %c |\r\n",i,i,i);
		else
		printf("| %.3d | %x | %c |",i,i,i);
	}
	printf("\r\n");

	return 0;
}

运行结果:

------------------------------------------------------------------------------------------------------------------------------

9、将居民身份证号(18位),抽取出生日,并输出年(7-10),月(11-12),日(13-14)。

#include<stdio.h>
#include<string.h>


char num[18]={0};
//char *ptr=NULL;

char birth[4]={0};
char *p=birth;

char *Intercept_str(char *str,int str_len,int start,int end);

int main()
{
here:
	printf("请输入18位身份证号码:");
	scanf("%s",num);
	
	if(strlen(num) == 18)
	{
		printf("你的身份证号码为:%s\r\n",num);
	p=Intercept_str(num,18,6,9);
		printf("您的出生日期为:%s",p);
	p=Intercept_str(num,18,10,11);
		printf("-%s",p);
	p=Intercept_str(num,18,12,13);
		printf("-%s\r\n",p);
	}
	else
	{
		printf("\r\n数据位数错误,请重新输入\r\n");
		goto here;	
	}
	
	
	return 0;
}


char aa[20]={0};
char *Intercept_str(char *str,int str_len,int start,int end)
{
	int j=0;
	for(int i=0;i<str_len;i++)
	{
		if(i>=start && i<=end)
		{
			aa[j++]=*(str+i);
//			printf("aa=%s\r\n",aa);
		}
	}
aa[j++]='\0';//防止返回值小于指针指向的数组
return aa;//不能返回局部变量,因为函数执行完后,局部变量内存会被回收(再访问就是非法)
}

输出结果:

------------------------------------------------------------------------------------------------------------------------------

10、指针的疑惑:为什么函数可以返回局部变量,却不能返回局部变量的地址:

答:函数调用完毕,两者都会背销毁,返回的局部变量是将(数值)拷贝一份,后续不用对其进行访问;而返回的局部变量地址,若后续对其访问,则是非法的。

另外:返回函数的局部静态变量的地址是有效的,因为静态变量地址不会被销毁。

另外:允许指向数组元素的指针与指向数组的最后一个元素后面的那个内存位置的指针比较;但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。

另外:数组名就是数组元素的首地址。除了:sizeof(aa);和&aa;这两种情况表示整个数组。

-----------------------------------------------------------------------------------------------------------------------------

11、输入两个整数范围(int)“-2^31~+2^31-1(2147483648~2147483647)”,交换两个数并输出

补充知识:

1 字节 8 位,4 字节就是 32 位:0000 0000 0000 0000 0000 0000 0000 0000

第一位是符号位,0 表示正数,那么最大值就是 0 111 1111 1111 1111 1111 1111 1111 1111

负数是以补码形式存储:所以-1其实是:该数值的反码+1:

1 000 0000 0000 0000 0000 0000 0000 0001 的反码+1,

1 111 1111 1111 1111 1111 1111 1111 1110 + 1 

#include<stdio.h>

void Exchange_addr(int *add1,int *add2);

int num1=0,num2=0;

int main()
{
	printf("输入两个数值(eg 1,2):");
	scanf("%d,%d",&num1,&num2);
	printf("the input number is num1=%d,num2=%d\r\n",num1,num2);	
	Exchange_addr(&num1,&num2);
	printf("the exchange number is num1=%d,num2=%d\r\n",num1,num2);	

return 0;
}

void Exchange_addr(int *add1,int *add2)
{
	int temp=0;
	temp = *add1;
	*add1 = *add2;
	*add2 = temp;
}

 运行结果:

--------------------------------------------------------------------------------------------------------------------------------

12、给定秒数,转化为时间:时、分、秒

#include<stdio.h>


unsigned int sec=0,min=0,hours=0,day=0,month=0,year=0;

unsigned long time=0;

int main()
{
	printf("请入如要转换的秒数:");
	scanf("%ld",&time);	
	hours=time/3600;
	min=time%3600/60;
	sec=time%3600%60;
	
	printf("\r\n%ld sec = %dh,%dmin,%dsec\r\n",time,hours,min,sec);

return 0;

}

-------------------------------------------------------------------------------------------------------------------------------

13、求每一位之和(如13456789)

#include<stdio.h>


int sum_dig(int n);

int main()
{
		
	
	printf("\r\nsum=%d\r\n",sum_dig(123456789));

return 0;
}



int sum_dig(int n)
{
	int sum = 0;

	while(n>0)
	{
		sum +=n%10;
		n /= 10;

		printf("\r\nsum=%d,n=%d\r\n",sum,n);
	}
	return sum;

}

运行结果:

文件的读写:最近有客户需求:Linux系统开机时候需要自动检测上次是否正常关机。

我的解决思路是,开机时候自启动服务判断某个标志文件,如果标志文件存在:为异常关机;标志不存在:为正常关机,同时再次创建(覆盖该标志文件)。 在关机服务中增加一个删除该标志文件的动作即可。

由于那个文件只涉及创建文件、删除文件和搭配shell脚本,所以我换了一个例子做记录:记录开机次数。

void main()
{
int i=0,num;
int a=0;

FILE *fout;
if((fout=fopen("num.txt","rw+"))==NULL){
	printf("\r\nthere is no num.txt here!\r\n");

	fout=fopen("num.txt","w");
	fprintf(fout,"%d",0);
	printf("\r\n创建名为num.txt的文档,设置初始开关机次数为:0\r\n");
	fclose(fout);
fout=fopen("num.txt","rw+");//reopen
//exit(1);
}


freopen("num.txt", "rw+", stdin);//read
scanf("%d", &num);//read
printf("\r\nnum=%d\r\n",num);

a=num;
a++;
fprintf(fout,"%d",a);//write+1
fclose(fout);

freopen("num.txt", "r", stdin);//read
scanf("%d", &num);//read
//fscanf(fout,"%d",num);//read
printf("\r\n开机次数=%d\r\n",num);


fclose(stdin);

}

效果:

附加:客户需求的demo

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

void main()
{
FILE *fout;
if((fout=fopen("ckl.txt","rw+"))==NULL){
	printf("\r\nthere is no ckl.txt here!\r\n");
	printf("\r\n上次正常关机了\r\n");

exit(1);
}


printf("\r\n上次异常关机\r\n");
fclose(fout);

if (remove("ckl.txt") == 0){
 
      printf("Removed ckl.txt\n");
 
   }else{
 
      perror("remove");
 
   }

}

效果:

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值