第二章 C语言基础程序设计

一概览

本章介绍以下内容:
- 变量
- 常量
- 进制及其转换
- 计算机信息存储
- C语言基本数据类型-整型
- C语言基本数据类型-浮点型
- C语言基本数据类型-字符型
- C语言基本数据类型-_Bool
- C语言基本数据类型-枚举
- 数据类型转换
- 实用案例

二 变量

2.1 什么是变量

程序在运行时,指令和数据都会被加载到内存中,当CPU从内存中读取指令和数据,根据不同的指令和数据进行各种计算(业务处理),从而产生不同的运算结果存放到内存中,而变量正是用来存储运算过程中随着不同业务逻辑产生对应运算结果的容器,至于能存数什么数据类型,取决于声明变量时指定的数据类型。

2.2 变量的声明

C语言是强类型的程序设计语言,这也就是意味着要想使用变量,必须要先声明,并完成初始化赋值后再使用,如果不赋值,就会产生垃圾结果。

#include "common.h"
/*
    编译器对变量的处理
*/
void varriable_compile(){

    int one, two, three;

    printf("one=%d,two=%d,three=%d",one,two,three); //得到三个垃圾变量值

    one = 1;
    two = 2;
    three = 3;

    printf("one=%d,two=%d,three=%d", one, two, three);

//  printf("four=%d",four); 这里会有编译错误,使用了未声明的变量


}

Visual Studio 2017的编译器强制变量必须完成初始化,否则无法通过编译
Visual Studio 2017的编译器强制变量必须完成初始化,否则无法通过编译

因为C语言不会像Java那样针对类中的每个成员变量的不同数据类型赋初始值,所以我们在C语言中声明变量时必须初始化变量的值。
声明变量的格式为 数据类型 变量名=变量值;
例如

int age =28; //声明一个整数类型的变量age,并赋值为28

有些C语言的编译器(例如VC2010以前的编译器或者GCC编译器没有开启C++11支持)还会要求在函数调用之前声明并初始化变量。

变量的数据类型可以是C语言支持的所有数据类型

变量命名不能以数字开头,可以包含字母数字下划线,建议变量的命名见名知意,有利于程序的维护和增强可读性。使用变量的时候还需要考虑到不同的编译器:VisualStudio2017提供了中文良好的支持(变量直接使用中文),而GCC编译器不支持中文。而且C语言严格区分大小写。

2.3 变量内存和CPU原理

该章节的代码采用VisualStudio2015编写和调试,在VisualStudio2017中不能编译

2.3.1 变量在内存中的存储机制

当在程序中声明一个变量并赋值时,编译器会针对数据类型开辟对应的内存空间存储变量值。
变量(变量地址,变量值)是存储在内存中,同一时间,变量地址和变量值是一一对应的,如下图:
变量在内存中的存储
编译器会维护一份变量表,表中记录了变量名、变量地址和变量值的对应关系,当使用一个未声明的变量时会提示找不到标识符。

#include "common.h"
/*
    变量声明后再使用
*/
void varriable_declare_use(){

//  printf("four=%d",four); 这里会有编译错误,使用了未声明的变量
}

2.3.2 运算与CPU寄存器

当声明变量并赋值,此过程是在内存中完成的,而一旦变量参与运算,此时由CPU来完成运算,将计算后的结果存储在CPU内部的寄存器中,然后传递给内存。
如下示例:

#include "common.h"
/*
    变量的赋值和算术运算在内存和CPU的的处理

*/
void varriable_cpu() {


    int one = 2; //只能给变量赋值,变量存储在内存中
    int two = one + 2; //运算是在CPU中完成

    printf("整数变量two的内存地址为%p\t,对应的变量值为%d \n",&two,two);

    two = one + 13;
    printf("整数变量two的内存地址为%p\t,对应的变量值为%d \n", &two, two);

    getchar(); //
}

这里可以使用C语言嵌套汇编,通过VisualStudio2017提供的调试功能观察CPU寄存器和内存地址以及变量值的变化过程。

#include "common.h"
/*
    使用汇编语言给变量赋值
*/
void varriable_assigment_asm() {

    int one = 0; //声明一个整数变量
    printf("整数变量one的内存地址为%p\t,对应的变量值为%d \n", &one, one);

    _asm {
        mov eax, 10
        mov one, eax
    }

    getchar();
    printf("整数变量one的内存地址为%p\t,对应的变量值为%d \n", &one, one);

    getchar();
}

示例代码中使用_asm{}嵌套了汇编代码,其中mov eax,10表示将整数10移动到寄存器eax中,mov one,eax表示将eax寄存器中的10赋值给整数变量one

接下来通过断点调试,观察执行过程中寄存器eax的变化过程
mov eax
由调试可知,当程序执行mov eax,10后,寄存器eax的值就变成了10。

mov one
而当执行mov one,eax时,整数变量one的值就变成了10

当变量在参与运算时,CPU执行逻辑运算并将结果存储在寄存器中

#include "common.h"

/*
    使用汇编语言完成算术运算
*/
void varriable_calc_asm() {

    int one = 0;
    printf("整数变量one的内存地址为%p\t,对应的变量值为%d \n", &one, one);

    _asm {
        mov eax, 10  //将10赋值给eax寄存器
        add eax,5 //10+5
        mov one,eax //将相加的结果赋值给变量one
    }

    printf("整数变量one的内存地址为%p\t,对应的变量值为%d \n", &one, one);

    getchar();
}

程序调试:
asm_add

2.4 变量交换

通常变量交换的方法就是通过一个中间变量临时存储其中一个变量的值,然后通过赋值实现的:

#include "common.h"

/*
    打印传递的字符串和两个整数的值
*/
void printinfo( char desc[],int one,int two) {

    printf(desc);
    printf( "one = %d \t two =%d\n",one,two);
}
/*

    第一种
    通过中间变量来实现赋值交换
*/
void var_temp_assign() {


    int one = 10;
    int two = 5;
    int tmp = 0;

    printinfo("交换之前",one,two);

    tmp = one; // one=10 tmp=10
    one = two; //two=5 one =5;
    two = tmp; //tmp=10 two=10

    printinfo("交换之后", one, two);

}

/*
    变量交换的几种方式
    @author tony tonytimemachine@gmail.com
    @date 2017/07/04 23:38
*/
void main() {


    var_temp_assign();
    system("pause");

}

该方法需要开辟临时内存空间来存储中间变量,如果此时有1千万个变量需要交换,需要考虑内存空间是否足够,以空间换取时间。

改进版:

/*

    通过算数运算来交换变量
*/
void var_alg_swap() {

    int one = 10;
    int two = 5;
    int tmp = 0;

    printinfo("算数运算交换之前", one, two);

    one = one + two; // one =15;
    two = one - two; //two=10;
    one = one - two; // one =5

    printinfo("算数运算交换之后", one, two);

}

相比上一种算法,不需要经过中间变量开辟临时存储空间。只需要经过算术运算即可完成两个变量的交换(需要注意计算结果的越界),但是计算的次数增多了,以时间换取空间。

最佳实现方式:

/*

    通过异或运算符来实现变量的交换
*/
void var_xor_swap() {

    int one = 10;
    int two = 5;
    int tmp = 0;

    printinfo("异或运算交换之前", one, two);

    one = one ^ two; // one =15;
    two = one ^ two; //two=10;
    one = one ^ two; // one =5
    printinfo("异或运算交换之后", one, two);

}

三 常量

3.1 什么是常量

常量一般是指程序从开始运行到结束进程的过程中不会改变的变量。
C语言中的常量可以使用两种方法实现;
第一种

#define constName constValue

其中constName表示常量名称,constValue表示值,通过该形式声明的常量没有内存地址,直接存储在寄存器中。不能直接和间接修改,是真正意义上的常量。

C语言能操作内存,不能操作寄存器。

第二种

const dataType=constValue;

在变量面前加上const修饰符,即可以将变量变为常量,通过该形式声明的常量可以通过指针修改。

3.2 C语言常量的使用案例

#include "common.h"

#define PI 3.1415926  //定义圆周率
#define height 8844 //定义珠穆朗玛峰的高度

/*
    使用define声明的常量
*/
void define_sample() {
    printf("圆周率为%.7f\n",PI); // %.7f 表示打印小数,小数点后保留7位数
    printf("珠穆朗玛峰的高度为%d\n",height);
}

/*
    使用const声明常量
*/
void const_sample() {

    const int age = 28; //初始化一个整数常量
    //age = 100; 编译错误,不能直接修改
    printf("改变之前age的值为%d\n",age);

     *(int*)&age=29; // &age表示获取age变量的地址  *表示根据地址取出内容 int*表示转换为非常量类型

    printf("改变后age的值为%d\n",age);

}

/*
    C语言常量的使用
    @author tony tonytimemachine@gmail.com
    @date 2017/07/03 23:08
*/
void main() {
    //define_sample();
    const_sample();
    system("pause");

}

使用#define定义的常量意义明确,可以实现批量修改。

四 进制

4.1 进制概述

在计算机的最底层,计算机数据都是采用二进制的补码来进行存储和运算的,但是为了方便使用,日常生活中使用更多的进制类型是十进制、十六进制、八进制。相同进制类型数据进行运算时会遵守加法:逢R进1;减法:借1当R,其中R就表示进制。
如下表格是它们的组成、示例和使用场景:

进制名称组成示例典型使用场景
二进制0,10101底层数据存储
八进制0-7012(以0开头)linux权限
十进制0-912整数
十六进制0-9,a-f12f数据的内存地址

c语言中的整数默认就采用十进制来表示。
c语言没有提供二进制的数据表现形式。

程序说明如下:

#include "common.h"
/*

    计算机中常用的三种进制的表示方法
    @author tony timemachine@gmail.com
    @date 201707/08 16:51
*/
void main() {

    int value = 110001; //C语言的整数不能定义成二进制的形式  这里默认为十进制的整数
    printf("value = %d \n ", value);

    int num = 012; // 8进制的整数是以0开头
    printf("八进制的012: num = %d\n",num);//1*8^1+2*8^0=8+2=10
    num = 0x12; //十六进制以0X开头,包含0-9,A-F组成
    printf("16进制的0x12: num = %d\n", num);//1*16^1+2*16^0=18
    system("pause");

}

4.2 二进制、八进制、十六进制转换

二进制转换为八进制或者十六进制相对于十进制而言是比较方便的。
因为3个二进制的整数对应1个八进制的整数。

二进制和八进制的对应关系如下表:

二进制八进制
0000
0011
0102
0113
1004
1015
1106
1117

二进制转八进制:在转换时,从右向左,每三位一组(不足三位用0补齐),转换成八进制。

011 100 =34

八进制转换二进制:每一位八进制数替代三位二进制数

012 =001 010

四位二进制的整数对应一位十六进制的整数。
二进制和十六进制的对应关系如下表:

二进制十六进制
00000
00011
00102
00113
01004
01015
01106
01117
10008
10019
1010a
1011b
1100c
1101d
1110e
1111f

二进制转十六进制:从右向左,每4位一组(不足4位,用0补齐),转换成十六进制。

11111011=fb
十六进制转二进制:每一位十六进制替代四位二进制数
12f=000100101111

4.3 二进制、八进制、十进制、十六进制转换

二进制、八进制、十六进制转换成十进制都是采用按权相加的形式计算的。

先看一个整数计算的案例:

1234=1*10^3+2*10^2+3*10^1+4*10^0=1000+200+30+4

因此可以采用按权相加的计算方式将二进制、八进制、十六进制转换为十进制

二进制转换为十进制:

100101=1*2^5+1*2^2+1*2^0=32+4+1=37

八进制转换为十进制

27=2*8^1+7*8^0=16+7=23

十六进制转换为十进制

20d=2*16^2+13*16^0=512+13=525

4.3 十进制、二进制转换

十进制整数转换为二进制:方法是除以2取余,直到商数为0,逆序排列,以22为例:倒序的二进制结果就是10110

计算过程如下:

22/2 余 0
11/2 余 1
5 /2 余 1
2/2 余 0
1/2 余 1
0

程序如下:

#include "common.h"
/*
  0-32767之间的十进制转换成二进制:除以2取余,直到商数为0,逆序排列
 @author tony timemachine@gmail.com
 @date 2017/07/09 11:26
*/
void convert() {
    int numbers[16] = {0}; //初始化一个16位整数数组,用于保存二进制整数
    printf("请输入一个需要转换成二进制的十进制正整数,取值范围在0-32767之间\n");

    int value = 0; //待转换的十进制整数
    scanf("%d",&value); //读取用户输入的整数 
    for (int i = 0; i < 15; i++) { //十六位二进制数,最高符号位为正整数

        int quotient = value/2; //商数
        int remainder = value%2; //余数
        value = quotient; //将除以2之后的商数赋值给value
        numbers[i] = remainder;//将余数存储在数组中

    }


    printf("十进制%d对应的二进制整数为",value);
    //逆序输出二进制
    for (int i = 15; i >= 0;i--) {
        printf("%d ",numbers[i]);
    }

    printf("\n");
    getchar();
}


void main(){

    convert();
    system("pause");
}

360面试题:
十进制小数转换为二进制:方法是乘以2,直到小数部分为0为止,取整顺序排列,以0.725为例:顺序排列的二进制结果就是0.11

0.725*2=1.5 取整 1
0.5*2=1 取整 1

五 计算机数据存储

计算机最底层的数据都是二进制的01010组成,因此最小的传输单位(国内宽带的网速就是以bit来计算的)为位 (bit),1bit可以存储的值为0或者1。因此百兆宽带的下载速度也就12.5MB。

字节(Byte)是计算机中最常用的基本存储单位,1个字节表示8个位, 它们之间的换算关系如下

1Byte=8bit

而在计算机的日常使用中,下载的速度通常是KB或者MB,MB和KB的换算关系为

1MB=1024KB

而KB和Byte的换算关系为:

1MB=1024KB

笔记本的移动硬盘或者服务器的硬盘通常都是GB或者TB

1GB=1024MB,1TB=1024GB

为什么32位操作系统只能使用4G不到的内存?
32位操作系统的寻址能力是2^32次方,换算关系如下:

4G=2^2*2^10*2^10*2^10=2^32

因为操作系统运行时还要占据一定的内存,所以4G内存条的可用内存大概是3.2G左右。
KB,MB,GB,TB之间是采用2^10也就是1024进行运算的。

随着数据的日益增长,以BAT为代表的互联网公司处理的海量数据已经达到PB级别,1PB到底有多大?

1PB=1024TB=1024*1024GB=1024*1024*1024MB=(2^30) MB

六 C语言数据类型

6.1 数据类型概述

数据类型是对程序所处理的数据(变量的类型,方法的返回类型)的”抽象”,将计算机中可能出现的数据类型进行分类,先上个C语言数据类型的全家福:
C语言数据类型
C语言中的数据类型所占据的内存空间是和操作系统相关,相同的数据类型在不同的平台上占据的内存空间可能是不一样的,可以使用sizeof关键字获取占据的内存空间大小,内存大小不同,存储的取值范围(极限)也会不同。

在使用数据类型时,必须提前了解占据的字节数量以及表示范围,如果越界则会发生错误的结果。

#include "common.h"
/*
    使用sizeof关键字查看数据类型占据的字节大小
    @author tony tonytimemachine@gmail.com
    @date 2017/07/09 12:43

*/
void sizeof_sample() {

    printf("char占据的字节数为%d字节\n",sizeof(char));
    printf("int占据的字节数为%d字节\n", sizeof(int));
    printf("long占据的字节数为%d字节\n", sizeof( long));
    printf("long long占据的字节数为%d字节\n", sizeof(long long ));
    printf("float占据的字节数为%d字节\n", sizeof(float));
    printf("double占据的字节数为%d字节\n", sizeof(double));


    printf("字符串1234 占据的字节数量为%d\n",sizeof("1234"));// 字符串默认以\0结尾 因此这里占据5个字节
    char val = 'A';
    printf("字符 A 占据的字节数量为%d\n",sizeof(val));

    int value = 10;

    printf("整数value占据的字节数量为%d\n",sizeof(value));

}

/*
    sizeof关键字查看数据类型的占据字节数量
    @author tony tonytimemachine@gmail.com
    @date 2017/07/09 12:43
*/
void main() {

    sizeof_sample();
    getchar();

}

6.2 整数

整数用于存储类似于订单数量,网站用户数等等的数据。
C语言中的整数按照从小到大可以分为short,int,long和long long四种,其中在16位系统(嵌入式)中,short和int占据的内存空间都是两个字节,而在32位系统上,int和long都是占据四个字节。

short的表示范围以及占据字节的数量案例

#include "common.h"
/*
    嵌入式场合使用short int
    @author tony timemachine@gmail.com
    @date 2017/07/10 23:03
*/
void short_int_sample() {

    short num_max = SHRT_MAX;
    short num_min = SHRT_MIN;

    printf("short占据的字节数量为\n",sizeof(short));
    printf("short表示的最小值为%d,short存储的最大值为%d\n",num_max,num_min);


    unsigned short unum_max = USHRT_MAX;
    unsigned short unum_min = 0;

    printf("无符号 short表示的最小值为%d,short存储的最大值为%d\n", unum_max, unum_min);
}

当然使用频率最高的整数还是int或者long long
同时整数默认就是带符号(signed),如果不考虑负数,还可以使用不带符号(unsigned)的整数,无符号的整数表示的最大值比带符号的整数范围更广。

整数还可以使用八进制、十进制和十六进制表示。

#include "common.h"
/*
    @author tony timemachine@gmail.com
    @date 
*/
void int_data_sample() {
    int one = 10; //默认是十进制整数
    int two = 010; //八进制整数
    int three = 0x10; //十进制整数
    int four = 10u; //无符号整数
    int five = 100l; //long  四字节
    long long six = 999999999999999LL;//long long 八个字节

    printf("six = %lld \n",six);
    //int long int 在32位以上的机器是等价的 都是占据4个字节
    //int short int 在16位机器上是等价的,占据2个字节
    signed  int int_max = INT_MAX;  //整数默认是有符号的(signed)
    int int_min = INT_MIN;

    long long_max = LONG_MAX;
    long long_min = LONG_MIN;

    unsigned long long ulong_max = ULLONG_MAX;
    printf("无符号的long long 存储的最大值为%llu",ulong_max);
    printf("int 占据的字节数量 %d \t long  占据的字节数量为%d\n",sizeof(int),sizeof(long));

    unsigned int uint_max = UINT_MAX;
}

整数的取值范围已经在limits.h头文件中使用常量定义,如下图:
limits.h

6.3 浮点数

浮点数表示数学意义上的小数,用于存储账户余额等等。
C语言中的浮点数可以分为float和double和long double三种,其中float占据四个字节,精确到小数点后6-7位,double占据八个字节,精确到小数点后15位,long double占据16个字节,可以用于超大型服务器的浮点数存储,C语言的浮点数默认是double类型,而浮点类型的数据可以采用数学中的小数(例如3.14)和指数计数法表示(2.34e5,其中e之前的数字称为尾数,e之后的数字称为指数,指数只能是整数,尾数表示与这个幂相乘)。

浮点数的极限范围定义在float.h头文件中

#include "common.h"


/*

    浮点数的案例
    @author tony timemachine@gmail.com
    @date 2017/07/12 1:11
*/
void main() {


    //float占据四个字节,浮点数默认是double 占据8个字节
    float value = 10.5;
    printf("float占据的字节数量为%d\n",sizeof(value));
    printf("10.5占据的字节数量为%d\n",sizeof(10.5));

    //浮点数可以使用指数表示法表示
    value = 1.23E5;
    printf("指数表示法表示浮点数的结果 value =%f\n",value);


    //float double long double占据的字节数量为 4 8 16
    printf("\nfloat占据的字节数量为%d,double占据的字节数量为%d,long double占据的字节数量为%d\n", sizeof(float), sizeof(double), sizeof(long double));


    float val1 = 1.00000000001;
    float val2 = 1.000000000002;
    printf("两个浮点数相比结果为%d\n",val1==val2); //输出结果为1 表示相等,因为超出了float精确到小数点后6位数

    printf("float表示的最小值为%.150f \n\n表示的最大范围值为%f\n",FLT_MIN,FLT_MAX);

    printf("\n\ndouble表示的最小值为%.750f \n\n表示的最大范围值为%f\n", DBL_MIN, DBL_MAX);




    getchar();


}

6.4 字符和字符串

6.4.1 字符

字符主要用于表示单个字母、数字和符号以及转义字符。
C语言中的字符使用char表示,char占据一个字节的空间,也就意味着可以存储256个整数。
在C语言中,一个字符变量占据一个字节,但是为了考虑兼容性,一个字符常量占据4个字节(以无符号整数的方式存储),而为了表示中文,采用宽字符(wchar_t)来存储,占据两个字节。

#include "common.h"

/*
    字符、款字符占据的字节数量
    @author tony tonytimemachine@gmail.com
    @date 2017 07/25 11:10
*/
void char_sizeof() {
    char ch = 'A';
    wchar_t wch = L'我'; //宽字符  兼容中文
    //'A'为了兼容和扩展宽字符,一般情况下占据4个字节 
    printf("\n字符占据的字节大小为%d\t 'A'占据的字节大小为%d",sizeof(ch),sizeof('A'));

    printf("\n宽字符占据的字节数量为%d\n",sizeof(wch));
}

C语言提供了两种输出字符的方式:分别是printf(“%c”)和putchar()

#include "common.h"

/*
    打印字符的方式
    @author tony tonytimemachine@gmail.com
    @date 2017 07/25 11:12
*/
void char_sample(){

    //使用printf和putchar函数实现字符输出
    char ch = 'A';
    printf("使用putchar函数输出字符变量ch的结果是");
    putchar(ch);
    printf("\n 使用printf 输出字符变量ch的结果是");
    printf("%c",ch);

    }

如果把一个字符当成整数输出,输出的是这个字符对应的ASC|码表的值。

#include "common.h"

/*

    字符和ASC码对应的关系
    @author tony tonytimemachine@gmail.com
    @date 2017 07/25 11:15
*/
void char_asc() {


    char ch = '1'; // 1个字节  每个字符对应一个编号
    printf("字符1对应的整数为%d\n",ch);

    int num = 1; //4个字节
    printf("整数1对应的字符是%c",num);


}
6.4.2 字符串

字符串表示用”“包含起来的字符序列,默认以\0结束(不显示),字符串中一个英文字符占据一个字节,一个中文字符占据2个字节。

#include "common.h"

/*
    英文字符串和中文字符串占据的字节数量
    @author tony tonytimemachine@gmail.com
    @date 2017 07/25 11:20
*/
void string_sizeof() {

    printf("英文字符串占据的字节大小为%d\n",sizeof("tony")); //字符串以\0结尾  5个字节
    printf("中文字符串占据的字节大小为%d\n",sizeof("刘光磊"));
}

不能将字符串赋值给字符变量,字符串也不能直接相加。

#include "common.h"
/*
    字符和字符串的使用事项
    @author  tonytimemachine@gmail.com
    @date 2017 07 25 12:05
*/
void string_sample() {

    char ch = "A "; //运行时会发生异常
    putchar(ch);


    char str1[2] = "A";
    char str2[2] = "B";;
    //str1 + str2;
}

使用sprintf实现打印字符串到变量中

#include "common.h"
*
    使用sprintf实现打印字符串到变量中
    @author  tonytimemachine@gmail.com
    @date 2017 07 25 12:20
*/
void change_color() {



    char str[100] = {0};

    while (1) {

        for (char c = '0'; c <= '9';c++) {

            sprintf(str, "color  %c%c", c, 'e'); //利用sprintf函数将字符串打印到str中
            system(str);
        }
    }

}

七 类型转换

在日常生活中,字符、整数和浮点数可以混合运算,不同数据间运算会进行自动类型转换,遵循低字节(char,short)向高字节转换(int ,long long,double)的原则,这样就可以保证计算的精度。

#include "common.h"
/*
    自动数据类型转换
    @author tony timemachine@gmail.com
    @date 2017/07/29 8:49
*/
void char_convert() {

    char ch = 'A';

    printf("ch 占据的字节数字为%d\n",sizeof(ch));

    printf("ch+1 占据的字节数字为%d\n", sizeof(ch+1)); //ch+1会发生自动类型转换,因为1int类型,因此会占据4个字节


}

计算结果的类型取决于参与计算的最大数据类型

#include "common.h"
/*
    低字节向高字节转换的案例
    @author tony timemachine@gmail.com
    @date 2017/07/29 8:55

*/
void convert_sample() {
    //计算表达式 10+'a'+1.5-8765.1234*'b'
    char c = 'a';
    int num = 10;
    double db = 1.5;
    double value = 8765.1234;
    char ch = 'b';

    printf("计算结果为%.6f", num+c+db-value*ch);

在某些业务场景中还需要使用强制类型转换:即在需要转换的数据前加上(强转类型),而在将大数据类型(double)转换为小数据类型(int)时会损失精度。

/*
    强制类型转换
    @author tony timemachine@gmail.com
    @date 2017/07/29 09:05
*/
void force_convert() {

    double one = 12.8;
    double two = 15.3;

    int calcResult = (int)one + two;

    printf("calcResult = %d \n",calcResult); //27

    calcResult = (int)(one + two); //28 
    printf("calcResult = %d \n", calcResult); 

}


/*
    赋值转换
    @author tony timemachine@gmail.com
    @date 2017/07/29 09:07

*/
void assigment_convert() {

    double db = 3; //自动类型转换

    printf("db = %f\n", db); //3


    int num = 6.7; //强制类型转换 大数据类型(double)转换为小数据类型(int)会发生精度损失

    printf("num = %d\n",num);//6


    double value = 4.5;
     num = (int)value; //类型转换是在CPU的寄存器完成的
     printf("num = %d\n", num);//4


}

八 数据类型案例

8.1 根据输入的三角形边长,计算三角形的面积。

需要借助math.h头文件中的sqrt函数实现

#include "common.h"


/*
    给定三角形的三边,计算面积
    @author tony timemachine@gmail.com
    @date 2017/07/12 1:35
*/
void calc_area() {


    //初始化三边长
    double  one = 0.0, two = 0.0, three = 0.0;
    printf("请输入三角形的边长");
    scanf("%lf",&one);


    printf("请输入三角形的边长");
    scanf("%lf", &two);


    printf("请输入三角形的边长");
    scanf("%lf", &three);

    double  p = (one + two + three) / 2;
    double S = sqrt(p*(p - one)*(p - two)*(p - three));

    printf("三角形的三边长分别为%f\t%f\t%f\n",one,two,three);
    printf("三角形的面积S=%f\n", S);

    getchar();

}


/*

    浮点数案例
    @author tony timemachine@gmail.com
    @date 2017/07/12 1:35
*/
void main() {

    calc_area();

    getchar();
}

8.2 已知中美GDP,计算多少年之后中国GDP超过美国

需要借助math.h头文件中的pow函数实现

#include "common.h"

/*

    计算中国GDP超过美国
    @author tony timemachine@gmail.com
    @date 2017/07/12 1:49
*/
void gdp() {

    double ch = 10.88;
    double am = 18.6;     //底数
    double chd = 1.07;
    double amd = 1.03;//增长率

    for (int i = 1; i <= 100; i++)
    {
        printf("\n中国%d年GDP=%f万亿美金", 2016 + i, ch*pow(chd, i));
        printf("美国GDP=%f", am*pow(1.03, i));
        printf("差距=%f", ch*pow(chd, i) - am*pow(1.03, i));
        if ((ch*pow(chd, i) - am*pow(1.03, i)) >0)
        {
            MessageBoxA(0,  "终于超越美国", "恭喜天朝", 0);
        }

    }


}


/*

    浮点数案例
    @author tony timemachine@gmail.com
    @date 2017/07/12 1:35
*/
void main() {
    gdp();
    getchar();
}

8.3 实现大小写字母相互转换

实现思路:通过ASC||码表可知,大写字母A对应的ASC||码表的编码值为65,小写字母为97,因此小写字母减32即可换算成大写字母,大写字母加上32即可换成小写字母。

#include "common.h"
/*
    大小写字母的转换
    @author tony tonytimemachine@gmail.com
    @date 2017 07/25 11:24

*/
void uplower() {

    printf("请输入需要转换的字母");
    char input = '\0'; //初始化字符变量
    scanf("%c",&input);

    getchar();

    if (input>='a'&&input<='z') {

        char lower = input - 0x20;
        printf("你输入的是小写字母\n转换成大写字母后的结果为%c", lower);
    }

    else if (input>='A'&&input<='Z') {
        char up = input + 0x20;
        printf("你输入的是大写字母\n转换成小写字母后的结果为%c", up);

    }


}

8.4 字符串的加密解密实现

实现思路:遍历字符串的字符,将其相加实现加密,将其相减时间解密

#include "common.h"



/*
    字符串的加密
*/
void encrypt(char str[]) {


    for (int i = 0; i < 5;i++) {

        str[i] += 1;
    }
    printf("加密之后的结果%s\n", str);

}

void decryption(char str[]) {

    for (int i = 0; i < 5; i++) {

        str[i] -= 1;
    }

    printf("解密之后的结果%s\n",str);
}

/*
    字符串的加密解密
    @author tony timemachine@gmail.com
    @date 2017 07/25 11:52
*/
void main() {

    char str[5] = {'c','a','l','c','\0'};

    system(str);

    encrypt(str);

    decryption(str);

    system("pause");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值