您的位置:首页 > 编程语言 > C语言/C++

C语言学习笔记一

2017-02-26 12:13 281 查看
1.知识点

二进制

  使用二进制作为计算机的进制是因为电子原件的状态有两种,一种是有电状态,一种是无电状态,同时这两种状态属于稳定状态,且可靠。

 

冯诺依曼体系结构

  特点:程序顺序进行

  组成:有输入,存储,运算,控制,输出

 

处理器

  CPU主频:计算机的运算能力

  CPU外频:主板的速率

  倍频:CPU主频/外频

  高速缓存:将要使用的数据

 

内存

RAM(随进存储器),ROM(只读存储器)

读取速度快,存储量小

 

删除

  使数据无效,将占用空间标志改为空闲状态。

 

硬盘

  读取速度慢,存储量大

 

BIOS/CMOS

  计算机启动时,加点,BIOS启动,其中包括自检程序,系统自举程序,中断程序(软件最底层)

 

语言的发展

  第一代语言:机器语言(0101)

  第二代语言:汇编语言(MOVAX,0x1)

  第三代语言:面向过程(C)

  第四代语言:面向对象(C++,JAVA)

 

C语言特点:

  拥有各种数据类型

  结构化控制语句,易读,易调试

  高效,

  可移植

 

2.知识点

进制转换

  (1)设整数为xyz,进制为m,则有公式:x*m^2+y*m^1+z*m^0

 

  (2)十进制转二,八,十六进制,除以对应进制(m),余数由上至下,对应数的由低到高

xyz/m=商……n1(余数)

商/m=商……n2(余数)

……

由此数为:商n2n1

 

  (3)二进制转十六进制,以4位为一个单位高位不足补0,按下表进行转换,十六进制转二进制则按表进行相反转换。

1  0001   2  0010    3 0011    4  0100

5  0101   6  0110    7 0111    8  1000

9  1001   A  1010    B 1011    C  1100

D  1101   E  1110    F 1111

 

  (4)二进制转十进制,按(1)公式,或者8421法则

 

  (5)十进制转二进制,按(2)公式,除2取余法则

 

运算法则

(1)加法

类似于带进位的或运算

 

(2)减法

B+B反=0ffh

B+B反+1=100h

B反+1=100h-B …… 求补运算

neg(b)=100h-b=~b+1

a-b=a+neg(b)  (进位丢失)

 

(3)乘法

二进制左移运算

a*(10011100)b=a*(2^7+……+2^0)=2^7*a+…+2^0*a

 

(4)除法

乘法再位移

a/c=a*(1/c)=a*((1*2^n)/(c*2^n))=a*(2^n/c)*(1/2^n)=a*M >> n

 

编译链接

cl 编译程序生成目标文件obj

/c 只编译,不链接

/W 1-4 编译强度

/WX 把警告视为错误

Link链接程序生成PE格式文件

重定向:hello.exe> test.txt

 #include <stdio.h>
int main()
{
printf("hello world");
return 0;
}



3.知识点

浮点编码

十进制小数转二进制小数

  小数部分*2取整数部分,知道小数部分为0

 0.75->0.75*2……1.5->0.5*2….1.0->0.11

 

  二进制小数转十进制小数

  小数部分是0.2^(-n)

 0.101->0.2(-1)+0.2(-3)->(1/2)+(1/8)->0.625

 

  定点小数存储

以小数点为界限分整数部分和小数部分存储,效率高,但灵活性低

 X1X2.X3X4  定点存储

 

浮点小数存储

以32位为例,seeeeeeee dddddddddddddddddddddd ,其中s表示符号位,用1位存储,e表示小数点移动的位数,用8位存储,d表示小数部分数据用23位存储

 X1.X2X3X4  浮点存储

 8.625->1000.101

 1.000101   小数点左移3位

  seeeeeeee ddddddddddddddddddddd

  010000010 00010100000000000000000    

*指数位符号判断取决于小数点向哪移动,如果小数点向整数部分移动则为正,如果向小数
e088
部分移动则为负

  01000001 0000 1010 0000 0000 0000 0000

 4    1   0   A   0   0   0    0

  0000 0A 41

 

 0.0625->0.0001

  1.0     小数点右移4位,则为-4+127 

  seeeeeeee dddddddddddddddddddddd

  00111 1011 000…00000

  00111101 1000 0000 0000 0000 0000 0000

 3    D   8   0   0    0  0    0

  0000 80 3D

为什么指数位要加127?

IEEE规定:当指数小于01111111时为负数,反之为正,01111111位0

ex3.1

/*
1. 使用printf() 函数显示下列菜单:
Menu
===================================
1. Input the students’ names and scores
2. Search scores of some students
3. Modify scores of some students
4. List all students’ scores
5. Quit the system
===================================
Please input your choise (1-5):
*/
#include <stdio.h>

void ShowMenu()
{
printf("\t\tMenu\r\n");
printf("===================================\r\n");
printf("1. Input the students’ names and scores \r\n");
printf("2. Search scores of some students\r\n");
printf("3. Modify scores of some students\r\n");
printf("4. List all students’ scores\r\n");
printf("5. Quit the system \r\n");
printf("=================================== \r\n");
printf("Please input your choise (1-5): \r\n");
}

int main ()
{
ShowMenu();
getchar();
return 0;
}

ex3.2
/*
2. 选择一种方法编写一个程序,实现输入
六个数输出最小数。
*/
#include <stdio.h>
#include <stdlib.h>

float mix(float x, float y)
{
float z;
if (x>y) z=y;
else z=x;
return z;
}

int main ()
{
float a,b,c,d,e,f,temp;
printf("Please input six numbers (a b c d e f):");
scanf("%f,%f,%f,%f,%f,%f",&a,&b,&c,&d,&e,&f);
temp=mix(a,b);
temp=mix(c,temp);
temp=mix(d,temp);
temp=mix(e,temp);
temp=mix(f,temp);
printf("%f,%f,%f,%f,%f,%f,the min is %f\n",a,b,c,d,e,f,temp);

system("pause");
return 0;
}ex3.3
/*
3. 编写一个程序,从键盘上输入华氏温度,屏幕显示对应的
摄氏温度。华氏温度和摄氏温度的转换公式为:
c=(f-32)/1.8
*/
#include <stdio.h>
#include <stdlib.h>

float cacl(float f)
{
float c = 0;
c = (f-(float)32.0f)/1.8f;
return c;
}

int main ()
{
float f = 0.0f;
float c = 0.0f;
printf("请输入华氏温度:");
scanf("%f", &f);
c = cacl(f);
printf("摄氏温度:%0.2f\r\n", c);
system("pause");
return 0;
}ex3.4
/*
4. 编程输出字符0、9、A、Z、a、z的ACSII码的十进制、八进制和十六进制的表示形式。
*/
#include <stdio.h>
#include <stdlib.h>

int main ()
{
int i = 0;
int j = 9;
char A = 'A';
char Z = 'Z';
char a = 'a';
char z = 'z';
printf("0的ACSII码的十进制为:%d\t八进制为:%o\t十六进制为:%x\r\n", 0, 0, 0);
printf("9的ACSII码的十进制为:%d\t八进制为:%o\t十六进制为:%x\r\n", 9, 9, 9);
printf("A的ACSII码的十进制为:%d\t八进制为:%o\t十六进制为:%x\r\n", A, A, A);
printf("Z的ACSII码的十进制为:%d\t八进制为:%o\t十六进制为:%x\r\n", Z, Z, Z);
printf("a的ACSII码的十进制为:%d\t八进制为:%o\t十六进制为:%x\r\n", a, a, a);
printf("z的ACSII码的十进制为:%d\t八进制为:%o\t十六进制为:%x\r\n", z, z, z);
system("pause");
return 0;
}ex3.5
/*
5. 编写一个程序,从键盘输入字符(例如’1’),转换成十进制数(即1),并输出。
提示:“1”的ASCII码为十进制数49,将其减去一个数等于十进制1即可。
*/
#include <stdio.h>
#include <stdlib.h>

int main ()
{
char c = '0';
printf("请输入字符:\n");
scanf("%c",&c);
if(c>='a'&&c<='z')
{
printf("%c的ASCII码的十进制为%d\n",c,c);
}
else if(c>='0' && c<='9')
{
int d;
d = c - 48;
printf("字符%c的十进制为%d\n",c, d);
}
else
{
printf("请输入0-9,a-z");
}

system("pause");
return 0;
}ex3.6
/*
6. 已知a=3,b=2,c=2.5,计算(float)(a+b)/3+(int)c的值。
*/
#include <stdio.h>
#include <stdlib.h>

int main ()
{
int a = 3;
int b = 2;
float c = 2.5;

float d = (float)(a+b)/3+(int)c;
printf("%f",d);

system("pause");
return 0;
}ex3.7
/*
7. 编写一个程序输出5!、10!的结果。
*/
#include <stdio.h>
#include <stdlib.h>

int funtion(int inum)
{
int result = 1;
int i;
if(inum == 0)
{
return 1;
}

for(i = 1; i < inum; i++)
{
result = result * (i+1);
}
return result;
}

int main ()
{
int a;
int b;
a = funtion(5);
b = funtion(10);
printf("%d\r\n", a);
printf("%d\r\n", b);
system("pause");
return 0;
}

ex3.8
/*
8. 编写一个程序,输入2个学生的姓名、学号、英语、数学、计算机成绩,输出这两个学生的姓名、学号和平均分。
*/
#include <stdio.h>
#include <stdlib.h>

int main ()
{
char name[31]; /*数组name[31]最多可以放30个字符或15个汉字*/
long num; /*其值超过32767的号码,需要用长整型*/
int eng,math,comp;
double aver;

char name2[31]; /*数组name[31]最多可以放30个字符或15个汉字*/
long num2; /*其值超过32767的号码,需要用长整型*/
int eng2,math2,comp2;
double aver2;

printf("Please input the first student's name:");
scanf("%s",name);
/*字符串用格式符"%s",并且数组名name前不需要取址符"&"*/
printf("Please input the first student's ID:");
scanf("%ld",&num); /*long型变量的格式符用%ld*/
printf("Please input first student scores (English math computer):");
scanf("%d%d%d",&eng,&math,&comp);

printf("Please input the secend student's name:");
scanf("%s",name2);
/*字符串用格式符"%s",并且数组名name前不需要取址符"&"*/
printf("Please input the secend student's ID:");
scanf("%ld",&num2); /*long型变量的格式符用%ld*/
printf("Please input secend student scores (English math computer):");
scanf("%d%d%d",&eng2,&math2,&comp2);

aver=(eng+math+comp)/3.0;
aver2=(eng2+math2+comp2)/3.0;

printf("the first student's named is %s , his ID is %ld ,his average score is %0.1lf \n",name,num,aver);

printf("the secend student's named is %s , his ID is %ld ,his average score is %0.1lf \n",name2,num2,aver2);

system("pause");
return 0;
}

ex3.9

/*
1.	写出58.25的16进制
58.25 -> 111010.01 -> 1.1101001
e:5+127
s eeeeeeee ddddddddddddddddddddddd
0 01111111
0101
0 10000100 11010010000000000000000
0100 0010 0110 1001 0000 0000 0000 0000
4    2    6    9    0    0    0    0
00 00 69 42

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

int main ()
{
printf("写出58.25的16进制:00 00 69 42\r\n");
system("pause");
return 0;
}


ex3,10
/*
2. 自己写程序查看float定义数据的内存。
*/
#include <stdio.h>
#include <stdlib.h>

int main ()
{
float f = 58.25f;
printf("%x", &f);
//printf("%x", f);
system("pause");
return 0;
}

ex3.11
/*
3. 将ascii码表打出来,并观察对应关系
*/
#include <stdio.h>
#include <stdlib.h>

int main ()
{
int i;
for(i = 0; i < 256; i++)
{
printf("ascii码十进制:%d->ascii码:%c\r\n", i, i);
}
system("pause");
return 0;
}

ex3.12
/*
4. 写程序将36由int转为char,和double并查看其内存值
*/
#include <stdio.h>
#include <stdlib.h>

int main ()
{
int i = 36;
char ch = (char)i;
double dnum = (double)i;
printf("%d, %c, %ld\r\n", i, ch, dnum);
system("pause");
return 0;
}

ex3.13
/*
5. 输入三角形的三个边的值(浮点型),求其面积
S=√[p(p-a)(p-b)(p-c)]
公式里的p为半周长:p=(a+b+c)/2
sqrt
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

double area(float a, float b, float c)
{
float p = 0.0f;
double S = 0.0;
p = (a+b+c)/2;
S = sqrt(p*(p-a)*(p-b)*(p-c));
return S;
}

int main ()
{
float a, b, c;
double result;
printf("请输入三角形的三个边a, b, c:");
scanf("%f,%f,%f", &a, &b, &c);
result = area(a, b, c);
printf("%lf\r\n", result);
system("pause");
return 0;
}

ex3.14
/*
6. 写程序说明一下int和long在内存中的区别,(即数据大小)
16位:int 2字节 long 4字节
32位:int 4字节 long 4字节
64位:int 8字节 long 16字节
*/
#include <stdio.h>
#include <stdlib.h>

int main ()
{
int i = 1;
long j = 1;

printf("%d\r\n", sizeof(int));//不同编译器中有差异
printf("%d\r\n", sizeof(long));
printf("%d\r\n", sizeof(long int));
system("pause");
return 0;
}

ex3.15
/*
7. 编程说明long double、long int和double long它们在内存中的区别
long double 8字节
long int 4字节
double long 8字节
*/
#include <stdio.h>
#include <stdlib.h>

int main ()
{
//不同编译器中有差异
printf("%d\r\n", sizeof(long double));
printf("%d\r\n", sizeof(long int));
printf("%d\r\n", sizeof(double long));
system("pause");
return 0;
}

4.知识点

代码规范

  以某一种规范为标准(谷歌,华为等)

 

Scanf用法

Scanf(“%7s”)   输入宽度

Scanf(“%[0-9]s”)  输入0-9的字符

Scanf(“%[2,4,5]s”)  输入2,4,5的字符

Scanf(“%[^5]s”)  输入除5以外的字符

 

内存分布

 0~7fffffff  为低地址空间,前64k系统保留,用作空指针检测等,后64K用作与ring0交互

 7fffffff~ffffffff  为高地址空间,属于系统内核部分

 

数据类型

  有符号的移位导致溢出问题,数据无效

  无符号的移位导致进位问题,数据部分有效

 

字符&字符串

  C类字符串:以‘\0’结尾,灵活性强

 Pascal类字符串:开头保存字符串数量,再保存数据,访问效率高

 

取模推导过程

 a/b=q….r

 a=qb+r

 r=a-qb

  余数的符号与被除数相同

  除法取整,C语言中是向0取整

 ex4.1

/*
模拟翻书,二分法

按比例查找:分前半部分和后半部分,再二分查找
在前后10页之内直接查找

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

/*
binSearch:模拟翻书,先对边界值进行缩小范围,在折半查找,如果nMid刚好在objPage
10页以内直接递减或递增
totalPage 书的每一页
objpage 要查找的目标页
nMax 最大页
return 如果找到返回页码的索引,否则返回-1

*/
int binSearch(int totalPage[], int objPage, int nMax)
{
int nLow, nHigh, nMid;
nLow = 0;
nHigh = nMax - 1;
if(objPage < totalPage[nHigh / 2])
{
nHigh = (int)nHigh / 2;
}
else if(objPage > totalPage[nHigh / 2])
{
nLow = (int)nHigh / 2;
}
else if(objPage == totalPage[nHigh / 2])
{
return nHigh / 2;
}
else
{

}
while(nLow <= nHigh)
{
nMid = (nLow + nHigh) / 2;
//查找的中间页码在目标页码的前后10页之内
if(totalPage[nMid] - objPage <= 10 && totalPage[nMid] - objPage > 0)
{
while(totalPage[nMid] != objPage)
{
nMid--;
}
return nMid;
}
if(objPage - totalPage[nMid] <= 10 && objPage - totalPage[nMid] > 0)
{
while(totalPage[nMid] != objPage)
{
nMid++;
}
return nMid;
}
//刚好相等
if(totalPage[nMid] == objPage)
return nMid;
if(totalPage[nMid] < objPage)
{
nLow = nMid + 1;
}
if(totalPage[nMid] > objPage)
{
nHigh = nMid - 1;
}

}
return -1;
}

int main()
{
int totalPage[100] = {0};
int n;
int nResultPage = 0;
int nPage = 1;
for(n = 0; n < 100; n++)
{
totalPage
= n + 1;
}
printf("请输入要查找的页码(1-100):");
scanf("%d", &nPage);
nResultPage = binSearch(totalPage, nPage, 100);
if(-1 == nResultPage)
{
printf("没找到!\r\n");
}
else
{
printf("%d\r\n", totalPage[nResultPage]);
}

system("pause");
return 0;
}

ex4.2
#include <stdio.h>
#include <stdlib.h>
// TODO: 大数阶乘
void main()
{
int res[65535] = {0};
long int carry = 0, num, digit = 1;
long int temp;
long int iCount, iCount1;
res[0] = 1;

scanf("%d", &num);
for (iCount = 2; iCount <= num; iCount++)
{
for (iCount1 = 1; iCount1 <= digit; iCount1++)
{
temp = res[iCount1 - 1] * iCount + carry;
res[iCount1 - 1] = temp % 10;
carry = temp / 10 ;
}

while (0 != carry)
{
res[digit++] = carry % 10;
carry = carry / 10;
}
}
digit = digit - 1;
for (digit; digit >= 0 ; digit--)
{
printf("%d", res[digit]);
}

printf("\n");
system("pause");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: