c语言不同数据类型能判断吗 (c语言数据类型编程练习题)

1. 类型转换

自动转换

自动类型转换就是编译器默默地、隐式地、偷偷地进行的数据类型转换,这种转换不需要程序员干预,会自动发生。

在赋值运算中,赋值号两边的数据类型不同时,需要把右边表达式的类型转换为左边变量的类型,这可能会导致数据失真,或者精度降低;所以说,自动类型转换并不一定是安全的。对于不安全的类型转换,编译器一般会给出警告。

#include<stdio.h>
void main() {
  float f = 100.34f;
  int n = f;
  printf("%d", n);
}

转换的规则如下:

  • 转换按数据长度增加的方向进行,以保证数值不失真,或者精度不降低。例如,int 和 long 参与运算时,先把 int 类型的数据转成 long 类型后再进行运算。
  • 所有的浮点运算都是以双精度进行的,即使运算中只有 float 类型,也要先转换为 double 类型,才能进行运算。
  • char 和 short 参与运算时,必须先转换成 int 类型。

c语言程序设计描述数据类型,c语言数据类型编程练习题

#include<stdio.h>
int main() {
    float PI = 3.14159;
    int s1, r = 5;
    double s2;
    s1 = r * r * PI;
    s2 = r * r * PI;
    printf("s1=%d, s2=%f\n", s1, s2);
    return 0;
}

c语言程序设计描述数据类型,c语言数据类型编程练习题

一个变态的自动转换

#include <stdio.h>
int main() {
    float d= 10 + 'a' + 1.5 - 8765.1234 * 'b';
    printf("total=%f", d);
    return 0;
}

强制类型转换

在代码中明确地提出要进行类型转换,这称为强制类型转换。

强制类型转换是程序员明确提出的、需要通过特定格式的代码来指明的一种类型转换。换句话说,自动类型转换不需要程序员干预,强制类型转换必须有程序员干预。

强制类型转换的格式为:

(type_name) expression

#include <stdio.h>
int main() {
    int sum = 103;  //总数
    int count = 7;  //数目
    double average;  //平均数
    average = (double)sum / count;
    printf("平均数:%f!\n", average);
    return 0;
}


sum 和 count 都是 int 类型,如果不进行干预,那么sum / count的运算结果也是 int 类型,小数部分将被丢弃;虽然是 average 是 double 类型,可以接收小数部分,但是心有余力不足,小数部分提前就被“阉割”了,它只能接收到整数部分,这就导致除法运算的结果严重失真。

类型转换只是临时性的

无论是自动类型转换还是强制类型转换,都只是为了本次运算而进行的临时性转换,转换的结果也会保存到临时的内存空间,不会改变数据本来的类型或者值。

#include <stdio.h>
int main() {
    double total = 200.48;
    int count = 5;
    double unit;
    int int_total = (int)total;
    unit = total / count;
    printf("total=%f,int_total=%d,unit=%f", total, int_total, unit);
    return 0;
}

c语言程序设计描述数据类型,c语言数据类型编程练习题

这里(int)total并不会改变total的值。

2. 跨平台移植的整数

不同平台,不同编译器,整数的大小不一样

int 16位系统下2个字节,32位下4个字节

在liunx 64位下是8个字节,对于Windows 32,64都是4个字节

#include<stdio.h>
void main() {
    printf("%d", sizeof(long));//输出4
}


在debain下编译输出

c语言程序设计描述数据类型,c语言数据类型编程练习题

引入stdint.h头文件解决此问题,需支持C99的编译器

c语言程序设计描述数据类型,c语言数据类型编程练习题

#include<stdio.h>
#include<stdint.h>
void main() {
    printf("%d", sizeof(int64_t));
}

3. bool类型

在 C 语言标准(C89)没有定义布尔类型,所以 C 语言判断真假时以 0 为假,非 0 为真。所以我们通常使用逻辑变量的做法:

用int来做标记

#include<stdio.h>

void main() {
  int flag;
  flag = 0;
  flag = 1;
}


宏定义布尔类型

//宏定义布尔类型
#define BOOL int
#define TRUE 1
#define FALSE 0

#include<stdio.h>

void main() {
  BOOL flag = TRUE;
  printf("%d", flag);
  flag = FALSE;
  printf("%d", flag);
}

在最新的 C 语言标准(C99)解决了布尔类型的问题。C99 提供了 _Bool 型,所以布尔类型可以声明为 _Bool flag。

_Bool 依然仍是整数类型,但与一般整型不同的是,_Bool 变量只能赋值为 0 或 1,非 0 的值都会被存储为 1。

#include<stdio.h>

void main() {
  _Bool b1 = 1;
  _Bool b2 = 2;
  _Bool b3 = 0;
  _Bool b4 = -5;
  printf("b1=%d,b2=%d,b3=%d,b4=%d", b1,b2,b3,b4);
}

c语言程序设计描述数据类型,c语言数据类型编程练习题

在C++中,通过bool来定义布尔变量,通过truefalse对布尔变量进行赋值。C99为了让我们能够写出与C++兼容的代码,添加了一个头文件<stdbool.h>

#include<stdio.h>
#include<stdbool.h>

void main() {
  bool b1 = true;
  bool b2 = false;
  bool b3 = 2 == 2;
  printf("%d,%d,%d", b1, b2,b3);
}


4. 基础数据类型进阶

浮点数数据丢失

void main() {
  float f1 = 3.14159264;
  printf("%f", f1);//小数点后6位,6位内正确,超出6位,不可预知

  float f2 = 3.14159263;
  if (f2 == f1) {
    printf("等于了!");
  }
}


double

void main() {
  double d1 = 1.123456789123456789123456789;
  printf("%f,%.20f", d1, d1);//1.123457,1.12345678912345681155
  //小数点后15位,15位内正确,超出15位,不可预知
}


#define _CRT_SECURE_NO_WARNINGS //关闭安全检查
#include<stdio.h>
#include<float.h>

void main() {
  float f;
  double d;
  long double ld;
  printf("%d,%d,%d\n", sizeof(f), sizeof(d), sizeof(ld));

  //分别输入
  scanf("%f", &f);
  scanf("%lf", &d);
  scanf("%Lf", &ld);

  printf("%f,%lf,%Lf\n", f, d, ld);

  printf("%f,$f\n", FLT_MAX, FLT_MIN);
  //在windows下max是一样的
  printf("%lf,%lf\n", DBL_MAX, DBL_MIN);
  printf("%Lf,%Lf", LDBL_MAX, LDBL_MIN);
}


#include<stdio.h>
#include<float.h>

void main() {
  double d1 = 1.11111111111111111111111113;
  double d2 = 1.11111111111111111111111112;
  if (d1 == d2) {
    printf("相等!");
  }
  double d3 = 1.11111111111111011101111113;
  double d4 = 1.11111111111111011111111112;
  if (d3 == d4) {
    printf("相等!");
  }
}


看一下float在内存中是怎么保存的

c语言程序设计描述数据类型,c语言数据类型编程练习题

查看32位浮点

一个float在内存中占4个字节,32个bit

c语言程序设计描述数据类型,c语言数据类型编程练习题

5. long double与long long

#include<stdio.h>
 
void main() {
  int num = 17600807885;
  printf("%d\n", num);//这个手机号存不对了
  long long mobile = 17600807885;
  printf("%lld\n", mobile);//需要lld
  printf("\n%d", sizeof("17600807885"));
}

#include<stdio.h>
#include<limits.h>
 
void main() {
  printf("%lld,%lld\n", LLONG_MAX, LLONG_MIN);
  printf("%llu", ULLONG_MAX);//无符号
}

6. 自动变量

函数中的局部变量,如不专门声明为static存储类别,都是动态地分配存储空间的,数据存储在动态存储区中。函数中的形参和在函数中定义的变量(包括在复合语句中定义的变量)都属此类,在调用该函数时系统会给它们分配存储空间,在函数调用结束时就自动释放这些存储空间,这类局部变量称为自动变量

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

void main() {
    int x = 10;
    auto int y = 9;
    auto int z = x + y;
    printf("%p,%d", &z, z);
}

void main() {
  int x = 10;
  auto y = 9;
  auto z = x + y;
  printf("%p,%d", &z, z);
}

c语言程序设计描述数据类型,c语言数据类型编程练习题

7. 基本输入输出

putchar函数字符输出函数,其功能是在终端(显示器)输出单个字符。其函数原型为:

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

void main() {
    putchar('A');
    putchar('av1');
    //输出A1
}

getchar函数的功能是接收用户从键盘上输入的一个字符。其一般调用形式为:

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

void main() {
  char c;  /*定义字符变量c*/
  c = getchar();  /*将读取的字符赋值给字符变量c*/
  printf("%c", c);
}

scanf函数称为格式输入函数,即按照格式字符串的格式,从键盘上把数据输入到指定的变量之中。

转换说明符

%c

把输入解释成一个字符

%d

把输入解释成一个有符号十进制整数

%e,%f,%g,%a

把输入解释成一个浮点数(%a是C99的标准)

%E,%F,%G,%A

把输入解释成一个浮点数(%A是C99的标准)

%i

把输入解释成一个有符号十进制整数

%o

把输入解释成一个有符号的八进制整数

%p

把输入解释成一个指针(一个地址)

%s

把输入解释成一个字符串:输入的内容以第一个非空白字符作为开始,并且包含直到下一个空白字符的全部字符

%u

把输入解释成一个无符号十进制整数

%x,%X

把输入解释称一个有符号十六进制整数

#define _CRT_SECURE_NO_WARNINGS

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

void main() {
  int num;
  printf("请输入一个数字:\n");
  scanf("%d", &num);//用地址接收
  printf("您输入的数字是:%d", num);
}


8. 两个例子

用户输入任务一数字,输出其对应的十进制,八进制,十六进制

#define _CRT_SECURE_NO_WARNINGS

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

void main() {
  int num;
  printf("请输入一个数字:\n");
  scanf("%d", &num);//用地址接收
  printf("您输入的数字是:%d,0%o,0x%x", num,num,num);
}


已知半径r,求一个圆的面积是多大。

#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>
#include<math.h>
#define PI 3.1415926

void main() {
  float num;
  printf("请输入一个半径:\n");
  scanf("%f", &num);//用地址接收
  printf("面积是:%5f",num*num*PI);
}