[Re] 数据类型&变量&算符

主函数&其他函数

主函数

一个完整的 C 语言程序,是由一个、且只能有一个 main()(又称"主函数",必须有) 和若干个其他函数结合而成(可选)。

main()是 C 语言程序的入口,程序是从 main() 开始执行。

其他函数

从函数定义的角度看,函数可分为 [系统函数] 和 [用户定义函数]。

  • 系统函数,即库函数:这是由编译系统提供的,用户不必自己定义这些函数,可以直接使用它们,如我们常用的打印函数 printf()
  • 用户定义函数:用以解决用户的专门需要。

第一个程序

# include<stdio.h>

int main(void) {
    printf("HelloWorld
"); // 
: 回车换行
    return 0;
}

include 头文件包含

  • #include 的意思是头文件包含,#include <stdio.h> 代表包含 stdio.h 这个头文件
    • std:标准库
    • i:输入 input
    • o:输出 output
    • .h:一个头文件
  • 使用 C 语言库函数需要提前包含库函数对应的头文件,如这里使用了 printf(),需要包含 stdio.h 头文件
  • #include<...>#include "..." 的区别
    • <> 表示系统直接按系统指定的目录检索
    • "" 表示系统先在 "" 指定的路径(没写路径代表当前路径) 查找头文件;如果找不到,再按系统指定的目录检索

花括弧、程序体和代码块

  • {} 叫代码块,一个代码块内部可以有一条或者多条语句
  • C 语言每句可执行代码都是 ; 分号结尾
  • 所有的 # 开头的行,都代表预编译指令,预编译指令行结尾是没有分号的
  • 所有的可执行语句必须是在代码块里面

注释

// ... 叫行注释,注释的内容编译器是忽略的,注释主要的作用是在代码中加一些说明和解释,这样有利于代码的阅读。

/* ... */ 叫块注释。块注释是C语言标准的注释方法。

printf 函数

printf 是 C 语言库函数,功能是向标准输出设备输出一个字符串。

return 语句

  • return 代表函数执行完毕,返回 return 代表函数的终止
  • 如果 main 定义的时候前面是 int,那么 return 后面就需要写一个整数;如果 main 定义的时候前面是 void,那么 return 后面什么也不需要写
  • main()return 0; 代表程序执行成功,return -1; 代表程序执行失败
  • int main()void main() 在 C 语言中是一样的,但 C++ 只接受 int main 这种定义方式

数据类型

C 的关键字

![](_v_images/20200923075708050_15355.png =400x)

数据类型

数据类型的作用:编译器预算对象(变量)分配的内存空间大小。

整型

#include <stdio.h>

int main() {
    int a = 123;	// 定义变量a,以10进制方式赋值为 123
    int b = 0567;	// 定义变量b,以8进制方式赋值为 0567
    int c = 0xabc;	// 定义变量c,以16进制方式赋值为 0xabc

    printf("a = %d
", a);
    printf("8进制:b = %o
", b);
    printf("10进制:b = %d
", b);
    printf("16进制:c = %x
", c);
    printf("16进制:c = %X
", c);
    printf("10进制:c = %d
", c);

    unsigned int d = 0xffffffff; // 定义无符号int变量d,以16进制方式赋值
    // 有符号整型数据,可以省略 signed
    printf("有符号方式打印:d = %d
", d);
    printf("无符号方式打印:d = %u
", d);
    return 0;
}

需要注意的是,整型数据在内存中占的字节数与所选择的操作系统有关。虽然 C 语言标准中没有明确规定整型数据的长度,但 long 类型整数的长度不能短于 int 类型, short 类型整数的长度不能长于 int 类型。

当一个小的数据类型赋值给一个大的数据类型,不会出错,因为编译器会自动转化。但当一个大的类型赋值给一个小的数据类型,那么就可能丢失高位。

字符型

字符型变量用于存储一个单一字符,在 C 语言中用 char 表示,其中每个字符变量都会占用 1 个字节。在给字符型变量赋值时,需要用一对英文半角格式的单引号 '' 把字符括起来。

字符变量实际上并不是把该字符本身放到变量的内存单元中去,而是将该字符对应的 ASCII 编码放到变量的存储单元中。char 的本质就是一个 1 字节大小的整型

#include <stdio.h>

int main() {
    char ch = 'a';
    printf("sizeof(ch) = %u
", sizeof(ch));

    printf("ch: %c
", ch); // 打印字符
    printf("ASCII: %d
", ch); // 打印 'a' 的 ASCII 值

    char A = 'A';
    char a = 'a';
    printf("a = %d
", a); // 97
    printf("A = %d
", A); // 65

    printf("A = %c
", 'a' - 32); // 小写 a 转大写 A
    printf("a = %c
", 'A' + 32); // 大写 A 转小写 a

    ch = ' ';
    printf("空字符:%d
", ch); // 空字符 ASCII 的值为 32
    printf("A = %c
", 'a' - ' '); // 小写 a 转大写 A
    printf("a = %c
", 'A' + ' '); // 大写 A 转小写 a

    return 0;
}

实型(浮点型)

实型变量也可以称为浮点型变量,浮点型变量是用来存储小数数值的。在 C 语言中, 浮点型变量分为两种: 单精度浮点数(float)、 双精度浮点数(double), 但是 double 型变量所表示的浮点数比 float 型变量更精确。

由于浮点型变量是由有限的存储单元组成的,因此只能提供有限的有效数字(默认 6 位)。在有效位以外的数字将被舍去,这样可能会产生一些误差。

不以 f 结尾的常量是 double 类型,以 f 结尾的常量(如 3.14f) 是 float 类型。

#include <stdio.h>

int main() {
    // 传统方式赋值
    float a = 3.1415f; //或 3.1415F
    double b = 3.1415926;

    // --------- 默认保留六位小数 ---------
    printf("a = %f
", a); // 3.141500
    printf("a(保留两位小数) = %.2f
", a); // 数据会四舍五入
    printf("b = %lf
", b); // 3.141593

    // 科学法赋值
    a = 3.2e3f; // 3.2*1000 = 3200,e可以写E
    printf("a1 = %f
", a); // 3200.000000

    a = 100e-3f; // 100*0.001 = 0.1
    printf("a2 = %f
", a); // 0.100000

    a = 3.1415926f;
    printf("a3 = %f
", a); // 3.141593

    return 0;
}

常量&变量

常量

  • 在程序运行过程中,其值不能被改变的量
  • 常量一般出现在表达式或赋值语句中
  • 定义常量
    • const 关键字修改的变量
    • 在程序首部用 #define 声明
#include <stdio.h>
// 2. 用 #define 声明一个常量
#define AGE 21.8

int main() {
    // 1. const 修饰的变量即为常量
    const float PI = 3.14159F;
    printf("PI: %f
", PI);
    printf("AGE: %f", AGE);
    return 0;
}

变量

  • 在程序运行过程中,其值可以改变
  • 变量在使用前必须先定义,定义变量前必须有相应的数据类型

运算符

算术运算符

赋值运算符

比较运算符

C 语言的比较运算中,"真" 用数字 1 来表示,"假"用数字 0 来表示。

逻辑运算符

位运算符

4 个位运算符用于整型数据,包括 char 将这些位运算符成为位运算的原因是它们对每位进行操作,而不影响左右两侧的位。请不要将这些运算符与常规的逻辑运算符(&&||!) 相混淆,常规的位的逻辑运算符对整个值进行操作。

按位取反 ~

一元运算符 ~ 将每个 1 变为 0,将每个 0 变为 1。

int main(void) {
    int a = 1;
    // .... 31 个 0 ....
    // 0000 ... 00000001
    // .... 按位取反 ....
    // 1111 ... 11111110
    // .... 30 个 0 ....
    // 1000 ... 00000010
    printf("%d", ~a); // -2
    return 0;
}

位与 &

二进制运算符 & 通过对两个操作数逐位进行比较产生一个新值。对于每个位,只有两个操作数的对应位都是 1 时结果才为 1。

int main(void) {
    int a = 10;
    int b = 67;
    // 00001010
    // 01000011
    // --------
    // 00000010
    printf("%d", a&b); // 2
    return 0;
}

位或 |

二进制运算符 | 通过对两个操作数逐位进行比较产生一个新值。对于每个位,如果其中任意操作数中对应的位为 1,那么结果位就为 1。

int main(void) {
    int a = 10;
    int b = 67;
    // 00001010
    // 01000011
    // --------
    // 01001011
    printf("%d", a|b); // 75
    return 0;
}

位异或 ^

二进制运算符 ^ 对两个操作数逐位进行比较。对于每个位,如果操作数中的对应位有一个是 1(但不是都是 1),那么结果是 1;如果都是 0 或者都是 1,则结果位 0。

int main(void) {
    int a = 12;
    int b = 67;
    // 00001100
    // 01000011
    // --------
    // 01001111
    printf("%d", a^b); // 79
    return 0;
}

C 也有一个组合的位异或+赋值运算符:^=

val ^= 0377
val = val ^ 0377

左移 <<

左移运算符 << 将其左侧操作数的值的每位向左移动,移动的位数由其右侧操作数指定。空出来的位用 0 填充,并且丢弃移出左侧操作数末端的位。该操作将产生一个新位置,但是不改变其操作数。左移 n 次等价于乘以 2 的 n 次幂。

int main(void) {
    // 0000 1010
    int a = 10;
    // 0001 0100
    printf("%d
", a<<1); // 20
    // 0010 1000
    printf("%d
", a<<2); // 40
    return 0;
}

右移 >>

右移运算符 >> 将其左侧的操作数的值每位向右移动,移动的位数由其右侧的操作数指定。丢弃移出左侧操作数有段的位。对于 unsigned 类型,使用 0 填充左端空出的位。对于有符号类型,结果依赖于机器。空出的位可能用 0 填充,或者使用符号(最左端) 位的副本填充。右移 n 次等价于除以 2 的 n 次幂。

数据类型转换

  • 数据有不同的类型,不同类型数据之间进行混合运算时必然涉及到类型的转换问题。
  • 转换的方法有 2 种:
    • 自动转换(隐式转换):遵循一定的规则,由编译系统自动完成。
    • 强制类型转换:把表达式的运算结果强制转换成所需的数据类型。
  • 类型转换的原则:占用内存字节数少(值域小) s的类型,向占用内存字节数多(值域大) 的类型转换,以保证精度不降低。

简单的位运算

打开位

  • flag = 10011010,将位 2 打开
    flag | 00000100
     (10011010)
    |(00000100)
    =(10011110)
    
  • 将所有位打开
    flag | ~flag
     (10011010)
    |(01100101)
    =(11111111)
    

关闭位

flag & ~flag

 (10011010)
&(01100101)
=(00000000)

转置位

转置(toggling) 一个位表示如果该位打开,则关闭该位;如果该位关闭,则打开。您可以使用位异或运算符来转置。其思想是如果 b 是一个位(1 或 0),那么如果 b 为 1,则 b^1 为 0;如果 b 为 0,则 b^1 为 1。无论 b 的值是 0 还是 1,0^b 为 b。

 (10010011)
^(11111111)
=(01101100)

交换两个数

int a = 6; // 0000 0110
int b = 7; // 0000 0111
a = a^b;   // 0000 0001
b = a^b;   // 0000 0110
a = a^b;   // 0000 0111
原文地址:https://www.cnblogs.com/liujiaqi1101/p/13724087.html