数据类型、变量、运算符
一、基本数据类型
需要掌握
所占字节数
不同类型之间的存储
不同类型数据之间的转换-隐式转换和强制类型转换
标准输出格式字符:
标准输出修饰符
1、所占字节数
char < int <= float < double (char 占一个字节)
long >= int
2、不同类型数据之间的转换
隐式类型转换:例如float+int 以及不同类型的混合运算大部分会自动转换成double型
强制类型转换:不会把强转的变量进行转换 只是一个过程 暂时把一个值进行改变
3、不同数据类型之间的存储
精度 指数 符号位 3.1234e-4
类型 位数 总位
float 1位-符号位 2~8位-指数位 9~32位-精度位 32
double 1位-符号位 2~11位-指数位 12~64位-精度位 64
float、double、long double等类型不允许直接进行位与操作符
4、正负数进制转换
正数:正数的二进制 对2取余
负数:正数的二进制 先取返 再加一 例4 00000100 -> 11111011 -> 11111100
注意:
%d 是输出带符号的十进制整数 如果定义的是unsigned int型 不要用%d输出
%u 是输出不带符号的十进制整数
课堂练习:
1、输出hello.c – 用exit(0)结束
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("hello word\n");
exit(0);
}
2、计算数据类型所占系字节数
运算符sizeof() 后跟类型或者变量名
%ld 返回值是整型或者long型
//用法:运算符sizeof() 后跟类型或者变量名 %ld 返回值是整型或者long型
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i = 23;
printf("sizeof(i)=%ld\n",sizeof(i));
printf("sizeof(int)=%ld\n",sizeof(int));
printf("sizeof(short)=%ld\n",sizeof(short));
printf("sizeof(long)=%ld\n",sizeof(long));
printf("sizeof(unsigned)=%ld\n",sizeof(unsigned));
printf("sizeof(unsigned short)=%ld\n",sizeof(unsigned short));
printf("sizeof(unsigned long)=%ld\n",sizeof(unsigned long));
printf("sizeof(float)=%ld\n",sizeof(float));
printf("sizeof(double)=%ld\n",sizeof(double));
printf("sizeof(char)=%ld\n",sizeof(char));
printf("sizeof(unsigned char)=%ld\n",sizeof(unsigned char));
exit(0);
}
输出结果:
经典面试题
1、判断float类型(32)的数是否相等
作用:利用sizeof关键字可以统计数据类型所占内存大小
语法: sizeof( 数据类型 / 变量)
#include <stdio.h> //( 不能使用 (i == j) )
#include <stdlib.h>
int main()
{
float i=123.123
if(fabs(i - 0) <= 1e-6) //判断是否等于0
if(fabs(i - 3) <= 1e-6) //判断是否等于3
exit(0);
}
2、
答:在运算过程中,如果参与运算的数据类型不同时,数据将由低类型转化为高类型,存储长度较短的转换为存储长度较长的,且不丢失精度,所以是float类型
3、
二、常量
C++定义常量两种方式
- #define 宏常量:
#define 常量名 常量值
- 通常在文件上方定义,表示一个常量
- const修饰的变量
const 数据类型 常量名 = 常量值
- 通常在变量定义前加关键字const,修饰该变量为常量,不可修改
代码中只支持 十进制 八进制 十六进制数
字符 十进制
NULL 0
字符0~9 :48~57
字母A~a :65~97
转义字符
\ddd :任意字符 \123 代表三位八进制数
\xhh:任意字符 \x14 代表二位16进制数
1、整型常量
2、实型常量
类型 位数 总位
float 1位-符号位 2~8位-指数位 9~32位-精度位 32
double 1位-符号位 2~11位-指数位 12~64位-精度位 64
3、字符常量
定义:有单引号引起来的单个字符或转义字符
合法的:’\n’ ‘a’ ‘\012’ ‘\xff’()
不合法: ‘\018’ \0是转义字符
4、字符串常量
双引号引起来的0个或多个字符 或 转义字符
“ab\018\x13cd” 有8个字符
5、标识常量
define [宏名] [宏体]
执行时宏名替换宏体 无条件替换
宏体不是单独的一个值需要添加括号 define MM (2+3)
define 相关面试题
三、变量
重要:生命周期 作用域 (参考UNIX环境高级编程7.6)
定义:[存储类型] 数据类型 标识符
int i,j;
[存储类型]:auto,register,static,extern可省
1、auto(默认)
随机值 只分配了空间不做任何初始化 在栈上
生命周期:从函数调用开始到结束
作用域:定义变量的函数或符合语句内
赋初值:每次调用时
#include <stdio.h>
#include <stdlib.h>
//当被重复定义的时候:每次被清理 再次被分配
void func()
{
int i = 1;
i = i + 1;
printf("i=%d\n",i);
}
int main()
{
func();
func();
func();
exit(0);
}
输出:i=2
i=2
i=2
2、static(静态)
默认0值 只会被定义一次 然后被继承
生命周期:程序整个运行期间
作用域:从定义开始到整个程序结束
赋初值:编译时赋初值,只赋一次
#include <stdio.h>
#include <stdlib.h>
void func()
{
int i = 1;
static int j = 1; //弱定义 有强定义时以强定义为
i = i + 1;
j = j + 1; //
printf("i: %p i=%d\n",&i,i); //打印地址
printf("j: %p j=%d\n",&j,j); //打印地址
}
int main()
{
func(); //当一次调用完成后 j的值会被继承
func(); //第二次进入函数的时候j的值会继承上次的值
func();
exit(0);
}
输出:
3、register:建议型
生命周期:从函数调用开始到结束
编译器会把该变量的空间存放到了寄存器中(不会存放到栈上) 速度更快
4、extern
扩大变量作用范围 是声明的不是用来定义的 就近原则
生命周期:程序整个运行期间
赋初值:编译时赋初值,只赋一次
//作用范围:从extern定义开始
#include <stdio.h>
#include <stdlib.h>
extern int i; //声明全局变量i
int main()
{
// i = 1;
printf("i=%d\n",i);
exit(0);
}
int i = 1;
输出:i = 1;
数据类型:基本类型 构造类型(数组) 指针类型
标识符:由数字、字母、下划线组成、不能以数字开头
值:与其数据类型相匹配
全局变量:从他定义开始知道程序结束 声明在外部
练习
1、打印默认int i、j的值 static i 的值 extern
#include <stdio.h>
#include <stdlib.h>
void func()
{
int i = 1;
static int j = 1; //弱定义 有强定义时以强定义为
i = i + 1;
j = j + 1; //
printf("i: %p i=%d\n",&i,i); //打印地址
printf("j: %p j=%d\n",&j,j); //打印地址
}
int main()
{
func(); //当一次调用完成后 j的值会被继承
func(); //第二次进入函数的时候j的值会继承上次的值
func();
exit(0);
}
四、运算符和表达式
优先级自己搜索:(1条消息) C语言运算符优先级(超详细)_兰宝的专栏-CSDN博客
1、算术运算符:
作用:用于处理四则运算
算术运算符包括以下符号:
运算符 | 术语 | 示例 | 结果 |
---|---|---|---|
+ | 正号 | +3 | 3 |
- | 负号 | -3 | -3 |
+ | 加 | 10 + 5 | 15 |
- | 减 | 10 - 5 | 5 |
* | 乘 | 10 * 5 | 50 |
/ | 除 | 10 / 5 | 2 |
% | 取模(取余) | 10 % 3 | 1 |
++ | 前置递增 | a=2; b=++a; | a=3; b=3; |
++ | 后置递增 | a=2; b=a++; | a=3; b=2; |
– | 前置递减 | a=2; b=–a; | a=1; b=1; |
– | 后置递减 | a=2; b=a–; | a=1; b=2; |
% :取模运算两边变量或者常量必须是整型
前置递增:变量名在后,先自增/减 ,再使用变量值
后置递增:变量名在前,先使用变量值,再进行自增/减
2、关系运算符
作用:用于表达式的比较,并返回一个真值或假值
比较运算符有以下符号:
运算符 | 术语 | 示例 | 结果 |
---|---|---|---|
== | 相等于 | 4 == 3 | 0 |
!= | 不等于 | 4 != 3 | 1 |
< | 小于 | 4 < 3 | 0 |
> | 大于 | 4 > 3 | 1 |
<= | 小于等于 | 4 <= 3 | 0 |
>= | 大于等于 | 4 >= 1 | 1 |
3、逻辑运算符
作用:用于根据表达式的值返回真值或假值
逻辑运算符有以下符号:
运算符 | 术语 | 示例 | 结果 |
---|---|---|---|
! | 非 | !a | 如果a为假,则!a为真; 如果a为真,则!a为假。 |
&& | 与 | a && b | 如果a和b都为真,则结果为真,否则为假。(短路特性) |
|| | 或 | a || b | 如果a和b有一个为真,则结果为真,二者都为假时,结果为假。 |
4、赋值运算符
作用:用于将表达式的值赋给变量
赋值运算符包括以下几个符号:
运算符 | 术语 | 示例 | 结果 |
---|---|---|---|
= | 赋值 | a=2; b=3; | a=2; b=3; |
+= | 加等于 | a=0; a+=2; | a=2; |
-= | 减等于 | a=5; a-=3; | a=2; |
*= | 乘等于 | a=2; a*=2; | a=4; |
/= | 除等于 | a=4; a/=2; | a=2; |
%= | 模等于 | a=3; a%2; | a=1; |
5、三目运算符:
op1 ? op2 : op3
t = a > b ? a : b //如果a>b 则t=a ,否则t=b
6、强制类型转换
不会把强转的变量进行转换 只是一个过程 暂时把一个值进行改变
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i;
float f = 3.9;
i = (int)f; //暂时把float类型转换成int型输出
printf("i = %d\n",i);
printf("f = %f\n",f);
exit(0);
}