参考书籍介绍
操作系统之哲学原理()
C程序设计(谭浩强)
计算机网络(谢希仁)
微机原理(清华大学出版社)
高级数据结构
C语言基本数据类型、运算符与表达式
基本类型及其所占字节
short(短整型) :2个存储单位
int (整型) :4个存储单位
long(长整型) :4个存储单位
float(单精度型):8个存储单元
long int :4个存储单元
long long:8个存储单元
long double:8个存储单元
bool:1个存储单元
注意:
- 1个存储单元(Byte)=8bit
- 类型是永远不会变的,即便是强制转换和隐式转换都只是转换值,类型没变
- size of():计算某类型所占字节个数
- char需要特别注意
e.g.
#include <stdio.h>
int main()
{ char a='E';
char b=70;
printf("a"=%c,a=%d\n",a,a);
printf("b"=%c,b=%d\n",b,b);
return 0;
}
这个代码输出时为a=E,a=69;b=F,b=70
可知当输出为整型时也能输出,输出的为ASCLL码
进制
进制之间可用贪心算法
e.g.
(119)10进制
=>> ( 01110111 ) 2进制
=>> ( 167 ) 8进制
=>> ( 77 ) 16进制
原、反、补码
数据在内存中以二进制形式存放,数值是以补码表示的
- 正数:源码=反码=补码
- 负数:源码取反变为反码+1为补码
e.g.
int i;
i=-10;
数据在内存中实际存放的情况
10 的原码 0000 0000 0000 1010
10 的反码 1111 1111 1111 0101
-10 的补码 1111 1111 1111 0110
注意,在存放整数的存储单元中,一般情况下,最左边的的一位用来表示符号,如果该位置为0表示正数,为1表示负数。
扩充空间字节
规则:
- 表示范围由大到小需要截断:int----->char 当一个字节(8位)放不下时,出现截断,直接取(最后一个字节)最后面8位
- 表示范围由小到大需要扩充:char----->int 2字节转化为4字节需要扩充8位。
扩充规则:有符号(1or0)扩充符号位
无符号(unsigned~):扩充0
通过几个例子看一下:
e.g.1:
# include <stdio.h>
int main()
{char a=25; //定义的是字符型变量char,所占一个字节
char b=-25;
int X=a;//定义的是整型变量char,所占四个字节
int Y=b;
printf("%x %x,x,y");
return 0;//输出为 19 FFFFFFE7
}
a=25 X输出为16进制后为19不再赘述
b=-25,b补码为 1110 0111 ----->Y补码为1111 1111 1111 1111 1111 1111 1110 0111则输出为FFFFFFE7
e.g.2:
# include <stdio.h>
int main()
{ char a=100;//注意输出为整型,所以占4个字节,a=0000 0000 0000 0000 0000 0000 0110 0100
char b=200;//b超出了char的范围(-128-127),200-256=-44,b=1111 1111 1111 1111 1111 1111 1100 1000
char c=a+b;//1 0000 0000 0000 0000 0000 0000 0010 1100
printf("%d %d\n,a+b,c");//临时子空间的a+b输出时截取为:0000 0000 0000 0000 0000 0000 0010 1100结果为44,而c为300,为300-256=44
unsigned char a=100;//注意为无定义的char, a=0000 0000 0000 0000 0000 0000 0110 0100
unsigned char b=200;// 此时的溢出为-44,b=0000 0000 0000 0000 0000 0000 1100 1000
unsigned cahr c=a+b;//临时子空间的+b输出时截取为:0000 0000 0000 0000 0000 0001 0010 1100结果为300,而c为300,300-256=44
printf("%d %d\n,a+b,c");//输出为300 44
return 0;
}
e.g.3:
# include <stdio.h>
int main()
{
char c = 128;//1111 1111 1000 0000
unsigned char uc = 128; //0000 0000 1000 0000
unsigned short us = 0;
us = c+uc; //1 0000 0000 0000 0000
printf("%x \n",us);//截取后输出为0
us = ( unsigned )c+uc;//考虑时可考虑临时空间c'=( unsigned )c,c'=0000 0000 1000 0000 uc=//0000 0000 1000 0000 c'+uc=0000 0001 0000 0000
printf("%x \n",us);//输出为100
us = c+(char)uc;//c:1111 1111 1000 0000 uc'=1111 1111 1000 0000,us=1 1111 1111 0000 0000
printf("%x \n",us);//截取后输出为ff00
return 0;
}
内存的存放
在C语言中,内存的存放方式为小端存放即数据的高字节保存在内存的高地址,而数据的低字节存放在内存的低字节
几种需要注意的运算符
- 取余、除法:
- 取余是二运算符元运算符,参与运算的量均为整型,求余运算的结果等于两数相除后的余数。特别注意求余符号的正负取舍和被除数符号相同。e.g.-3%16=-3;16%-3=1
- 除法运算符“/”。二元运算符。参与运算的量均为整型时,结果为整型,舍去小数。如果运算量中有一个为实型,结果为双精度实型。
e.g…:5/2=2,1/2=0,5/2.0=2.5
- 自增运算符:b1=++a;b2=a++的区别。
第一个是先将a+1再赋值给b1运算,第二个是先将a赋值给b2,再将a自加1。第一个是先将a+1再赋值给b1运算,第二个是先将a赋值给b2,再将a自加1
printf(%d,-3++)//输出为-3
- 逻辑或和逻辑与
逻辑或||: a>0 || a+1 若a>0为真时不需要运算,为假时再算a+1
逻辑与&&:a<0&&a++,a<0为假时停止运算,为真时继续计算
if语句实现结构
if(条件语句){}: 其中{}内非真即假,只要为零就是假其余都是真。
-
if(表达式) 语句
-
if(表达式) 语句 1 else语句2
-
if(表达式1) 语句 1
else if(表达式2)语句2
else if(表达式3)语句3
else 语句4 -
if语句的嵌套(遵循就近原则)
if
if()语句1
else 语句2
else
if()语句3
else 语句4
e.g.将a,b,c按从小到大排列
#include <stdio.h>
int main()
{ int a,b,c,tmp;
scanf("%d %d %d",&a,&b,&c);
if(a<b)
else {tmp=a;a=b;b=tmp;}
if(a<c)
else {tmp=a;a=c;c=tmp;}
if(b<c)
else {tmp=b;b=c;c=tmp;}
printf("%d,%d,%d\n",a,b,c);
return 0;
}
作业练习
1.猜数字游戏:
#include<stdio.h>
# include<stdlib.h>
# include<time.h>
int main()
{
int guess=0;//定义一个猜测值
int count=0//定义一个计数器
srand(time (NULL));//随机种子,保证每次的随机数不一样
int c=rand()%100;//定义一个随机数在0--99之间
while (1)
printf("please guess a number between 0-99:\n");
scanf("%d,&guess");
count++;//计数器
if (a > guess)//对比
{ printf("Too low!\n"); }
else if
(a < guess)//对比
{ printf("Too high!\n"); }
else
{ printf("Congratulations, you guessed it:%d times.\n",count);//输出
return 0; } }
2.判断是否为闰年
#include<stdio.h>
void main()
{
int year;//定义一个输入年份
int leap;//定义一个判断真假
printf("please input a year:");//闰年的定义是:能被4整除同时不能被100整除,或者能被400整除。
scanf("%d",&year);
if(year%4==0)
{
if(year%100==0)
{
if (year%400==0)
leap=1;
else
leap=0;
}
else
leap=1;
}
else
leap=0;
if(leap)
printf("%d is a leap year ",year);
else
printf("%d is not a leap year",year);
}
3.输入年份和月份,判断这一年的这一个月有多少天?
#include<stdio.h>
void main()
{
int year;//定义一个输入年份
int leap;//定义一个判断真假
int month;//定义一个输入月份
printf("请输入年月形式为××××年××月:\n");
scanf("%d年%d月 ",&year,&month);
If month ==2//判断是否为2月
if(year%4==0)//讨论为闰年还是平年
{
if(year%100==0)
{
if (year%400==0)
leap=1;
else
leap=0;
}
else
leap=1;
}
else
leap=0;
if(leap)
printf("该月有29天\n");//闰年29天
else
printf("该月有28天\n");//平年28天
}
else {
switch(month )
{
case1,3,5,7,8,10,12 :print("该月有31天\n");
case4,6,9,11 :print("该月有30天\n");
default:print("月份输入错误");
}
}
4.输入年月日,判断为这一年的第几天。
#include<stdio.h>
void main()
{
int year;//定义一个输入年份
int leap;//定义一个判断真假
int month;//定义一个输入月份
int day;//定义一个输入日
int sum;//定义一个天数的加和
printf("请输入年月形式为××××年××月××日:\n");
scanf("%d年%d月%d日 ",&year,&month,&day);
switch(month)//先把月份天数算清楚
{
case 1:sum=0;break;
case 2:sum=31;break;
case 3:sum=59;break;
case 4:sum=90;break;
case 5:sum=120;break;
case 6:sum=151;break;
case 7:sum=181;break;
case 8:sum=212;break;
case 9:sum=243;break;
case 10:sum=273;break;
case 11:sum=304;break;
case 12:sum=334;break;
default:printf("data error");break;
}
sum=sum+day;//加上日的天数
if(year%4==0)//判断年为闰年的情况
{
if(year%100==0)
{
if (year%400==0)
leap=1;
else
leap=0;
}
else
leap=1;
}
else
leap=0;
if(leap==1&&month>2){
sum++;
}
printf("这是这一年的第%d天",sum);
printf("\n");
}