云计算百科
云计算领域专业知识百科平台

C语言自学——C语言数据类型和变量

1. 数据类型介绍

        C语言的基本数据类型包括整型、浮点型和字符型。整型用于存储整数,浮点型用于存储小数,字符型用于存储单个字符。下面盘点一下C语言提供的各种数据类型,本章节主要探讨内置数据类型。

1.1、字符型

        字符型(char)是C语言中用于存储单个字符的数据类型,占用1字节内存空间。字符型变量实际存储的是对应字符的ASCII码值(整数),因此可以直接参与整数运算。

char
[signed] char
unsigned char

char ch1 = 'A'; // 直接赋值字符
char ch2 = 65; // 使用ASCII码赋值(十进制)
char ch3 = '\\x41'; // 使用ASCII码赋值(十六进制)
char ch4 = '\\101'; // 使用ASCII码赋值(八进制)

1.2、整型

//短整型
short [int]
[signed] short [int]
unsigned short [int]

//整型
int[signed] int
unsigned int

//⻓整型
long [int]
[signed] long [int]
unsigned long [int]

//更⻓的整型
//C99中引⼊
long long [int]
[signed] long long [int]
unsigned long long [int]

1.2.1类型修饰符
  • signed

    • 显式声明为有符号整型(默认情况下,int、short、long等为有符号)。
    • 示例:signed int i = -10;
  • unsigned

    • 声明为无符号整型,只能表示非负数。
    • 示例:unsigned int j = 10;
    • 无符号整型只能表示非负数,范围是相应有符号整型的非负部分的两倍。
  • 1.3、浮点型

    float
    double
    long double

    1.3.1、浮点型数据类型

    C语言中的浮点型用于表示小数或实数,主要包含以下三种类型:

    • float:单精度浮点型,占用4字节(32位),精度约6-7位小数。
    • double:双精度浮点型,占用8字节(64位),精度约15-16位小数。
    • long double:扩展精度浮点型,通常占用10字节(80位)或更多,具体取决于编译器。
    1.3.2、浮点型声明与初始化

    浮点型变量可以通过以下方式声明和初始化:

    float a = 3.14f; // 注意后缀'f'表示float类型
    double b = 2.71828; // 默认浮点常量是double类型
    long double c = 1.41421356L; // 后缀'L'表示long double

    1.3.3、浮点型常量表示

    浮点型常量支持科学计数法:

    • 十进制形式:3.14、0.001
    • 指数形式:1.23e-4(表示1.23×10⁻⁴)
    1.3.4、浮点型精度与范围
    • float:范围约±1.2×10⁻³⁸到±3.4×10³⁸。
    • double:范围约±2.3×10⁻³⁰⁸到±1.7×10³⁰⁸。
    • long double:范围通常更大,具体取决于实现。
    1.3.5、浮点型的注意事项

    浮点型运算可能存在精度误差,例如:

    float x = 0.1f + 0.2f;
    printf("%.20f\\n", x); // 输出可能不是精确的0.3

    比较浮点数时应使用误差范围(如fabs(a – b) < 1e-6)。

    1.3.6、常用数学函数

    C标准库<math.h>提供浮点运算函数:

    #include <math.h>
    double sqrt(double x); // 平方根
    double pow(double x, double y); // 幂运算
    double sin(double x); // 三角函数

    1.4、布尔类型

            C语言原来并没有为布尔值单独设置⼀个类型,而是使用整数 在 C99 中也引入了 布尔类型,是专门表示真假的。从C99标准开始,C语言引入了_Bool关键字和<stdbool.h>头文件,提供了更直观的布尔类型支持。

    #include <stdbool.h>

    bool flag = true; // 定义布尔变量并初始化为真
    flag = false; // 修改为假

            布尔值可以参与逻辑运算:

    bool a = true, b = false;
    bool c = a && b; // 逻辑与
    bool d = a || b; // 逻辑或
    bool e = !a; // 逻辑非

            隐式类型转换

            当其他类型转换为布尔类型时,零值转为false,非零值转为true:

    _Bool b = 10; // b的值为1(true)
    b = 0.0; // b的值为0(false)

    1.5、各种数据类型的长度

            每一种数据类型都有自己的长度,使用不同的数据类型,能够创建出长度不同的变量,变量长度的不 同,存储的数据范围就有所差异

    1.5.1、sizeof操作符

            sizeof 是⼀个关键字,也是操作符,专门是用来计算sizeof操作符数的类型长度的,单位是字节。 sizeof 操作符的操作数可以是类型,也可是变量或者表达式。它可以在编译时求值,返回一个 size_t 类型的无符号整数。

            可以直接对数据类型使用 sizeof,例如:

    size_t int_size = sizeof(int); // 返回 int 类型的大小

            可以对变量使用 sizeof,无需括号(除非是类型名):

    int x;
    size_t x_size = sizeof x; // 返回变量 x 的大小

            对数组使用 sizeof 会返回整个数组的字节大小:

    int arr[10];
    size_t arr_size = sizeof(arr); // 返回 10 * sizeof(int)

            对指针使用 sizeof 返回指针本身的大小(通常为 4 或 8 字节,取决于系统):

    int *ptr;
    size_t ptr_size = sizeof(ptr); // 返回指针的大小,而非指向的数据大小

            sizeof中表达式不计算

    #include <stdio.h>
    int main()
    {
    short s = 2;
    int b = 10;
    printf("%d\\n", sizeof(b = b + 1));
    //表达式b = b + 1的类型为int(因b是int类型),所以sizeof返回int的字节数(通常为4)
    printf("s = %d\\n", s);
    return 0;
    }

    2. signed 和unsigned

            C语言使用signed 和 unsigned 关键字修饰字符型和整型类型的。signed 关键字,表示⼀个类型带有正负号,包含负值; unsigned 关键字,表示该类型不带有正负号,只能表示零和正整数。 对于 int 类型,默认是带有正负号的,也就是说由于这是默认情况,关键字 int 等同于 signed int 。 signed ⼀般都省略不写,但是写了也不算错。

    signed int a;
    //等同于int a;

            可以将 int 类型声明为无符号形式,仅表示非负整数,此时需使用 unsigned 关键字。使用 unsigned 声明整型变量的优势在于:相同内存空间下,可表示的最大整数值将扩大一倍。

    unsigned int a;

            unsigned int里面的int可以省略,写成下面这样:

    unsigned a

            字符类型 char 也可以设置 signed 和 unsigned 。

    signed char c;
    //范围为-128 到127
    unsigned char c;
    // 范围为0到255

            需要注意的是,C语言规定char类型默认是否带符号取决于当前系统。这意味着char并不等同于unsigned char。这一点与int不同,int默认等同于signed int。

    3. 数据类型的取值范围

            C语言中的基本数据类型及其取值范围主要取决于编译器和系统架构(如32位或64位)。以下是常见数据类型的典型取值范围:

    3.1、整型
  • char

    • 大小:1字节(8位)
    • 有符号:-128 到 127
    • 无符号:0 到 255
  • short

    • 大小:2字节(16位)
    • 有符号:-32,768 到 32,767
    • 无符号:0 到 65,535
  • int

    • 大小:通常4字节(32位)
    • 有符号:-2,147,483,648 到 2,147,483,647
    • 无符号:0 到 4,294,967,295
  • long

    • 大小:4字节(32位系统)或8字节(64位系统)
    • 32位有符号:-2,147,483,648 到 2,147,483,647
    • 64位有符号:-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807
    • 无符号:0 到 18,446,744,073,709,551,615(64位)
  • long long

    • 大小:8字节(64位)
    • 有符号:-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807
    • 无符号:0 到 18,446,744,073,709,551,615
  • 3.2、浮点型
  • float

    • 大小:4字节(32位)
    • 范围:约 1.2E-38 到 3.4E+38
    • 精度:6-7位小数
  • double

    • 大小:8字节(64位)
    • 范围:约 2.3E-308 到 1.7E+308
    • 精度:15-16位小数
  • long double

    • 大小:通常10字节(80位)或更高
    • 范围:更大,具体取决于实现
  • 3.3、获取具体值的代码示例

            可以使用 <limits.h> 和 <float.h> 头文件获取具体编译环境下的取值范围:

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

    int main() {
    printf("char range: %d to %d\\n", CHAR_MIN, CHAR_MAX);
    printf("int range: %d to %d\\n", INT_MIN, INT_MAX);
    printf("float range: %e to %e\\n", FLT_MIN, FLT_MAX);
    return 0;
    }

    3.4、注意事项
    • 实际取值范围可能因编译器或平台不同而变化,建议使用标准库宏(如 INT_MAX)获取具体值。
    • 无符号类型的最小值始终为 0,最大值可通过 UINT_MAX 等宏获取。

    4. 变量

    4.1、变量的创建

            了解清楚了类型,我们使用类型做什么呢?类型是用来创建变量的。什么是变量呢?C语言中把经常变化的值称为变量,不变的值称为常量。

    data_type name;
    | |
    | |
    数据类型 变量名

    int age; //整型变量
    char ch; //字符变量
    double weight; //浮点型变量

            变量在创建的时候就给⼀个初始值,就叫初始化。

    int age = 18;
    char ch = 'w';
    double weight = 48.0;
    unsigned int height = 100;

    4.2、变量的分类
    • 全局变量:定义在大括号外的变量称为全局变量。其作用域覆盖整个工程,可以在任何地方调用使用。

    • 局部变量:定义在大括号内的变量称为局部变量。其作用范围仅限于定义它的代码块内部,无法在外部使用。

    #include <stdio.h>

    int global = 2023;//全局变量
    int main()
    {
    int local = 2018;//局部变量
    printf("%d\\n", local);
    printf("%d\\n", global);
    return 0;
    }

    #include <stdio.h>
    int n = 1000;
    int main()
    {
    int n = 10;
    printf("%d\\n" n);//打印的结果是多少呢?
    return 0;
    }

            如果局部和全局变量同名的时候,局部变量优先使用。

            在C/C++语言中,变量根据作用域不同存储于内存的不同区域:

  • 局部变量:存储在栈区,函数调用时自动分配,函数返回时自动释放
  • 全局变量:存储在静态区,程序运行期间始终存在
  • 动态分配内存:使用堆区进行管理,通过malloc/new申请,free/delete释放
  • 5. 算术操作符:+、-、*、/、%

    5.1、算术操作符概述

    C语言提供五种基本算术操作符,用于执行数值计算:

    • +:加法
    • -:减法
    • *:乘法
    • /:除法
    • %:取模(求余数)
    5.2、加法操作符 +

            用于计算两个操作数的和。

    int result = 5 + 3; // result = 8

            支持整数和浮点数运算,结果为操作数类型。

    5.3、减法操作符 –

            用于计算两个操作数的差,或表示负数。

    int diff = 10 – 4; // diff = 6
    int neg = -5; // neg = -5

    5.4、乘法操作符 *

            用于计算两个操作数的乘积。

    int product = 6 * 7; // product = 42

    5.5、除法操作符 /

     执行除法运算,结果取决于操作数类型:

    • 整数除法:截断小数部分(向零取整)。
    • 浮点数除法:保留小数部分。

    int div_int = 10 / 3; // div_int = 3
    float div_float = 10.0 / 3.0; // div_float ≈ 3.333…

    5.6、取模操作符 %

            返回整数除法的余数,仅适用于整数类型。

    int remainder = 10 % 3; // remainder = 1

            若操作数为负数,结果符号依赖编译器实现(通常与被除数一致)。

    5.7、优先级与结合性

    算术操作符的优先级从高到低:

  • *、/、%(同级,左结合)
  • +、-(同级,左结合)
  •         使用括号可显式控制运算顺序:

    int value = (2 + 3) * 4; // value = 20

    5.8、注意事项
    • 整数除以零导致运行时错误。
    • 浮点数除以零可能返回 INF(无穷大)或 NaN(非数字)。
    • 取模操作符不可用于浮点数。

    6. 赋值操作符:=和复合赋值

    6.1、基础赋值操作符(=)

            在 C 语言中,= 是基础的赋值操作符,用于将右侧表达式的值赋给左侧的变量。语法形式为:

    variable = expression;

            赋值操作符的优先级较低,通常结合方向为从右向左。例如:

    int a, b;
    a = 5; // 将 5 赋给变量 a
    b = a + 3; // 计算 a + 3 并将结果赋给 b

    6.2、复合赋值操作符

    复合赋值操作符结合了赋值与算术/位运算,简化代码并提升可读性。常见形式包括:

    • +=(加法赋值)
    • -=(减法赋值)
    • *=(乘法赋值)
    • /=(除法赋值)
    • %=(取模赋值)

            语法形式为:

    variable op= expression;
    // 等价于 variable = variable op (expression)

            示例:

    int x = 10;
    x += 5; // x = x + 5 → 15
    x *= 2; // x = x * 2 → 30

    6.3、注意事项
    • 右结合性:复合赋值操作符从右向左计算。例如 a += b *= 2 等价于 a += (b *= 2)。
    • 表达式求值顺序:右侧表达式会先计算,再与左侧变量运算。
    • 类型匹配:需确保左右操作数类型兼容,否则可能触发隐式类型转换或警告。

    7. 单目操作符:++、–、+、

    7.1、自增操作符 ++

            用于将操作数的值增加1,分为前缀(++a)和后缀(a++)两种形式。

    • 前缀形式:先自增,再使用变量的值。计算口诀:先+1,后使用;

      int a = 5;
      int b = ++a; // a先变为6,再赋值给b
      printf("%d, %d", a, b); // 输出: 6, 6

    • 后缀形式:先使用变量的值,再自增。计算口诀:先使用,后+1

      int a = 5;
      int b = a++; // b赋值为5,a随后变为6
      printf("%d, %d", a, b); // 输出: 6, 5

    7.2、自减操作符 —

            用于将操作数的值减少1,同样分为前缀(–a)和后缀(a–)。

    • 前缀形式:先自减,再使用变量。计算口诀:先-1,后使用。

      int a = 5;
      int b = –a; // a变为4,b赋值为4

    • 后缀形式:先使用变量,再自减。计算口诀:先使用,后-1

      int a = 5;
      int b = a–; // b赋值为5,a变为4

    7.3、正号操作符 +

            表示数值的正值(通常省略),但可用于强制类型转换或明确表达式语义。

    int a = -10;
    int b = +a; // b为-10(无实际变化)

    7.4、负号操作符 –

            对操作数取负值。

    int a = 10;
    int b = -a; // b为-10

    7.5、注意事项
  • 副作用:++和–会修改操作数的值,避免在同一个表达式中多次使用同一变量的自增/自减。

    int a = 5;
    int b = a++ + a++; // 未定义行为

  • 类型限制:++和–仅适用于变量,不能用于常量或表达式(如5++非法)。

  • 结合性:单目操作符从右向左结合。例如,-+-a等价于- (+ (-a))。

  • 8. 强制类型转换

    int a = 3.14;//a的是int类型, 3.14是double类型,两边的类型不⼀致,编译器会报警告

            为了消除这个警告,我们可以使⽤强制类型转换:

    int a = (int)3.14;//意思是将3.14强制类型转换为int类型,这种强制类型转换只取整数部分

            我们使用强制类型转换都是万不得已的时候使用,如果不需要强制类型转化 就能实现代码,这样自然更好的

    9. scanf和printf介绍

    9.1、printf
            9.1.1、基本用法:

            printf是C语言标准库中的输出函数,用于向标准输出(如屏幕)打印格式化数据。它名字里的f代表format(格式化),表示可以定制输出文本的格式。

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

            printf() 是在标准库的头⽂件 stdio.h 定义的。使用这个函数之前,必须在源码文件头部引入这 个头文件。

            9.1.2、占位符

            所谓“占位符”,就是这个位置可以⽤其他值代入。    

    #include <stdio.h>
    int main()
    {
    printf("There are %d apples\\n", 3);
    return 0;
    }

           在上面的示例中,"There are %d apples\\n"是输出文本,其中的%d作为占位符,表示该位置将被其他值替换。占位符的首字符始终为百分号%,第二个字符则代表占位符的类型。例如%d表示此处必须填入一个整数值。

            常用的占位符除了%d之外,还有%s用于表示字符串的插入。

    #include <stdio.h>
    int main()
    {
    printf("%s will come tonight\\n", "zhangsan");
    return 0
    }

            9.1.3、占位符列举

            以下按字母顺序列出 C 语言中常用的 printf() 占位符,每种占位符对应不同的数据类型:

    • %a:十六进制浮点数(字母小写)
    • %A:十六进制浮点数(字母大写)
    • %c:字符
    • %d:十进制整数
    • %e:科学计数法浮点数(指数部分小写 e)
    • %E:科学计数法浮点数(指数部分大写 E)
    • %f:小数(包含 float 和 double 类型)
    • %g:6 位有效数字浮点数(自动转为科学计数法时指数部分小写 e)
    • %G:同 %g(指数部分大写 E)
    • %hd:十进制 short int 类型
    • %ho:八进制 short int 类型
    • %hx:十六进制 short int 类型
    • %hu:unsigned short int 类型
    • %i:整数(基本等同于 %d)
    • %ld:十进制 long int 类型
    • %lo:八进制 long int 类型
    • %lx:十六进制 long int 类型
    • %lu:unsigned long int 类型
    • %lld:十进制 long long int 类型
    • %llo:八进制 long long int 类型
    • %llx:十六进制 long long int 类型
    • %llu:unsigned long long int 类型
    • %Le:科学计数法表示的 long double 类型浮点数
    • %Lf:long double 类型浮点数
    • %n:记录已输出的字符数量(不显示,仅存储到变量)
    • %o:八进制整数
    • %p:指针
    • %s:字符串
    • %u:unsigned int 类型
    • %x:十六进制整数
    • %zd:size_t 类型
    • %%:输出百分号(%)
            9.1.4、限定占位符宽度

    int num = 42;
    printf("%5d", num); // 输出 " 42"(右对齐,宽度5)
    printf("%-5d", num); // 输出 "42 "(左对齐,宽度5)

            在上面的示例中,%5d表示该占位符的宽度至少为5个字符。如果数值不足5位,系统会在值的前面添加空格进行填充。默认情况下,输出内容采用右对齐方式,因此会在数字前添加空格;如需改为左对齐(在数字后添加空格),只需在占位符的%后添加-符号即可。

            小数部分的限定符用于控制所有数字的最小显示宽度。

    // 输出 " 123.450000"
    #include <stdio.h>
    int main()
    {
    printf("%12f\\n", 123.45);
    return 0;
    }

            在上面的示例中,%12f表示输出的浮点数至少占据12位宽度。由于默认显示精度为小数点后6位,因此输出23.45时,结果前会添加2个空格。

            9.1.5、总是显示正负号

            默认情况下, printf() 不对正数显⽰ + 号,只对负数显示号。如果想让正数也输出 + 号,可 以在占位符的 % 后⾯加⼀个 + 。

    #include <stdio.h>
    int main()
    {
    printf("%+d\\n", 12); // 输出 +12
    printf("%+d\\n", -12); // 输出 -12
    return 0;
    }

            9.1.6、限定小数位数

            如需控制小数位数,可通过格式化占位符实现。例如,保留两位小数可使用"%.2f"格式。

    // 输出Number is 0.50
    #include <stdio.h>
    int main()
    {
    printf("Number is %.2f\\n", 0.5);
    return 0;
    }

            这种写法可以与限定宽度占位符,结合使用。

    // 输出为" 0.50"
    #include <stdio.h>
    int main()
    {
    printf("%6.2f\\n", 0.5);
    return 0;
    }

            最小宽度和小数位数这两个参数,都可以使用*来指定,并通过printf()函数进行动态传入。

    #include <stdio.h>
    int main()
    {
    printf("%*.*f\\n", 6, 2, 0.5);
    return 0;
    }
    //等同于printf("%6.2f\\n", 0.5);

            9.1.6、输出部分字符串

       %s 占位符用于输出字符串,默认会显示完整内容。若只需显示开头部分,可使用%.[m]s格式,其中 m 代表要显示的字符数。

    // 输出hello
    #include <stdio.h>
    int main()
    {
    printf("%.5s\\n", "hello world");
    return 0;
    }

    9.2、scanf
    9.2.1、scanf 基本用法

    scanf 是 C 语言中用于从标准输入(如键盘)读取数据的函数,其基本语法为:

    scanf("%d", &i);

            它的第⼀个参数是⼀个格式字符串,里面会放置占位符(与编译器如何解读用户的输入,需要提取的数据是什么类型。 这是因为C语言的数据都是有类型的,(与printf() 的占位符基本一致),scanf() 必须提前知道用户输入的数据类型,才能处理数据。 它的其余参数就是存放用户输入的变量,格式字符串里面有多少个占位符,就有多少个变量。 上面示例中, scanf() 的第一个参数 %d ,表示用户输入的应该是一个整数。 %d 就是⼀个占位 符, % 是占位符的标志, d 表示整数。第⼆个参数 &i 表示,将用户从键盘输入的整数存入变量 i 。

    示例:

    int num;
    scanf("%d", &num); // 读取一个整数并存入 num


    9.2.2、scanf 返回值

    scanf 返回成功匹配并赋值的输入项数量。若输入与格式不匹配或遇到文件结束符(如 Ctrl+D/Ctrl+Z),返回 EOF(通常为 -1)。

    示例:

    int a, b;
    int count = scanf("%d %d", &a, &b);
    // 若输入 "10 20",count 为 2;若输入 "10 abc",count 为 1。


    9.2.3、常用占位符

    scanf 的占位符需与变量类型严格匹配:

    占位符类型示例
    %d int scanf("%d", &x);
    %f float scanf("%f", &y);
    %lf double scanf("%lf", &z);
    %c char scanf("%c", &c);
    %s 字符串(char[]) scanf("%s", str);
    %u unsigned int scanf("%u", &u);
    %x 十六进制整数 scanf("%x", &h);

    注意事项:

    • %s 读取字符串时遇到空格或换行符停止,可能引发缓冲区溢出(建议用 fgets 替代)。
    • %lf 是 double 类型专用,float 需用 %f。

    9.2.4、赋值忽略符 *

    在占位符前加 * 可忽略输入项(不赋值给变量),常用于跳过不需要的数据。

    示例:跳过输入中的日期部分:

    int year, month;
    scanf("%d-%*d-%d", &year, &month); // 输入 "2023-05-15",month 为 15,中间 05 被忽略

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » C语言自学——C语言数据类型和变量
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!