C语言学习笔记一

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    

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

  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] = 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");
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值