数据类型
字符数据类型
类型
写法
大小
字符数据类型
char
1
短整型
short
2
整形
int
4
浮点型(单精度)
float
4
长整型
long
4
更长整型
long long
8
双精度
double
8
赋值
1 2 3 4 5 6 7 8 9 10 int main () v{ int age = 18 ; char *name = "caixukun" ; short num = 20 ; float weight = 55.5 ; double d = 6.66 ; printf ("%d\n" , 100 ); return 0 ; }
计算机单位
bit - 比特
byte - 字节 = 8字节
kb - 1024 byte
mb
gb
tb
pb
常量与变量
变量
写法
含义
备注
%d
整数
%f
浮点数
%lf
双精度
%c
打印字符
配合printf可以用ASCII码打印对应字符
%s
打印字符串
分类
全局变量
{} 外部定义的
局部变量
{} 内部定义的
优先级
出现同名时,==局部变量优先==
1 2 3 4 5 6 7 8 9 #include <stdio.h> int num = 10 ;int main () { int num = 1 ; printf ("%d\n" , num); return 0 ; }
例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #define _CRT_SECURE_NO_WARNINGS 1 //放在代码第一行,取消scanf报错显示 #include <stdio.h> //头文件 int main() { int a = 0; int b = 0; int sum = 0; printf("请输入两个数字"); scanf("%d %d", &a, &b);//&取地址 //scanf是vs提供的,只能在vs里写,不是C语言标准 //scanf()是输入函数 sum = a + b; printf("sum= %d\n", sum); return 0; }
作用域
变量的适用范围
局部变量
==局部范围==,例如大括号内
全局变量
整个工程
1 2 3 4 5 6 7 8 extern int v_gal = 1 ;int main () { printf ("%d\n" , v_gal); return 0 ; }
生命周期
变量的生命周期是指变量创建销毁的时间段
局部变量的生命周期是{}内
全局变量是整个程序内
常量
字面常量
const修饰的常变量
1 2 3 4 5 6 7 8 9 10 # include <stdio.h> int main () { int arr[10 ] = {0 }; int n = 10 ; const int arr2[n] = {0 }; return 0 ; }
define定义的标识符常量
1 2 3 4 5 6 7 8 9 #define MAX 10000; int main () { int n = MAX; printf ("n = %d\n" , n); return 0 ; }
枚举常量
可以 一一列举 的常量,值是0,1,2…(默认从0开始)
例如:男女、三原色、星期
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 enum Sex { MALE, FEMALE, SECRET, }; int main () { enum Sex s = MALE; printf ("%d\n" ,MALE); printf ("%d\n" ,FEMALE); printf ("%d\n" ,SECRET); return 0 ; }
字符串
是用双括号引起的一串字符
结束标志是\0
(诡计多端的0)
结束标志不算在长度中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #include <stdio.h> #include <string.h> int main () { char arr[] = "hello" ; char arr1[] = "abc" ; char arr2[] = {'a' , 'b' , 'c' }; printf ("%s\n" , arr1); printf ("%s\n" , arr2); int len = strlen ("abc" ); printf ("%d\n" ,len); printf ("%d\n" , strlen (arr1)); printf ("%d\n" , strlen (arr2)); return 0 ; }
转义字符
转变了原来的意思
1 2 3 4 5 int main () { printf ("ab\c" ); return 0 ; }
转义字符
释义
例子
?
书写多个问号时使用,防止被解析为三字母词
比如??)会被解析为]
’
用于表示字符常量
输出普通的单引号’
"
用于表示一个字符串内部的双引号
一个原理
|用于表示反斜杠
一个原理
\a
警告字符,蜂鸣
让电脑响一下
\b
退格符
\f
进纸符
\n
换行
\r
回车
\t
水平制表符
等同于按tab
\v
垂直制表符
\ddd
ddd
表示1~3个八进制数字
如:\130 X
\xdd
dd
表示2个十六进制数字
如:\x30 0
1 2 3 4 5 6 int main () { printf ("%c\n" ,'\130' ); printf ("%d\n" , strlen ("\328" )); return 0 ; }
注释
用于解释复杂代码
注释方法有两种
C++注释方法
C注释法
分别在上下两行,以/*
为始,以*/
为终
支持嵌套注释
选择语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #define _CRT_SECURE_NO_WARNINGS 1 int main () { int input = 0 ; printf ("卢本伟牛逼逼\n" ); printf ("要开挂吗(0/1)?" ); scanf ("%d" , &input); if (input == 1 ) { printf ("我没有开挂\n" ); } else { printf ("开挂死全家\n" ); } return 0 ; }
循环语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 int main () { int line = 0 ; while (line<30000 ) { printf ("写代码:%d\n" , line); line++; } if (line == 30000 ) { printf ("您已成功飞升\n" ); } return 0 ; }
函数
引用函数就是在套娃使用,自定义函数也是这个原理,利用函数可以方便实现各种功能的快速使用
1 2 3 4 5 6 7 8 int main () { int num1 = 0 ; int num2 = 0 ; scanf ("%d%d" , &num1, &num2); int sum = num1 + num2; return 0 ; }
和以下代码等价
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 int Add (int x, int y) { int z = 0 ; z = x + y; return z; } int main () { int num1 = 0 ; int num2 = 0 ; scanf ("%d%d" , &num1, &num2); int sum = Add(num1,num2); return 0 ; }
数组
存储一组相同类型的元素的集合
1 2 3 4 5 6 7 8 9 10 11 12 13 int main () { int i = 0 ; int arr[10 ] = {1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 }; while (i < 10 ) { printf ("%d " , arr[i]); i++; } return 0 ; }
操作符
算术操作符
1 2 3 4 5 6 7 int main () { int a = 9 / 2 ; float b = 9 / 2.0 ; return 0 ; }
移位操作符
移动的是二进制位
向左移动一位就是变成2 2 2^2 2 2 倍
位操作符
赋值操作符
符号
含义
备注
=
+=
-=
*=
/=
&=
^=
|=
>>=
<<=
1 2 3 4 5 6 7 int main () { a = a + 5 ; a +=5 ; return 0 ; }
单目操作符
符号
含义
备注
!
逻辑反操作
-
负值
+
正值
&
取地址
sizeof
操作数的类型长度(以字节为单位)
~
对一个数的二进制按位取反
–
前置、后置–
前置先加加再使用,后置先使用再加加
++
前置、后置++
*
间接访问操作符(解引用操作符)
()
强制类型转换
1 2 3 4 5 6 int main () { int a = (int )3.14 ; printf ("%d\n" , a); return 0 ; }
逻辑操作符
条件操作符
exp1 ? exp2 : exp3
exp1成立,exp2计算,整个表达式结果是exp2的结果
exp1不成立,exp3计算,整个表达式结果是exp3的结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 int main () { int a = 0 ; int b = 3 ; int max = 0 ; if (a>b) max = a; else max = b; max = a > b ? a : b; return 0 ; }
逗号表达式
exp1, exp2, exp3
从左向右依次计算,整个表达式的结果是最后一个表达式的结果
下标引用、函数调用、结构成员
[] () . ->
常见关键字
auto
是自动的,每个局部变量都是auto修饰的
register
寄存器关键字
大量频繁使用的数据放在里面提高使用效率
signed
有符号的
unsigned
union
联合体(共用体)
typedef
类型重定义,重命名(别名)
1 2 3 4 5 6 7 8 typedef unsigned int u_int;int main () { unsigned int num = 100 ; u_int num2 = 100 ; return 0 ; }
void
无-空
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 void test () { int a = 1 ; a++; printf ("%d " , a); } int main () { int i = 0 ; while (i<10 ) { test(); i++; } return 0 ; }
static
静态的,本质是改变了变量a的存储类型
修饰局部变量
让局部变量变成类似全局变量
修饰全局变量
把全局变量的外部链接性改为内部链接性(静态),使得这个全局变量不能被其他文件连接使用
修饰函数
使得函数只能在自己所在的源文件内部使用,其他源文件不能使用
本质上是改变链接属性(外部->内部),和修饰全局变量类似
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 void test () { static int a = 1 ; a++; printf ("%d " , a); } int main () { int i = 0 ; while (i<10 ) { test(); i++; } return 0 ; }
内存划分
区
备注
栈区
局部变量,函数的参数
堆区
动态内存分配的!!
静态区
全局变量,static修饰的静态变量
extern
声明外部符号
1 2 3 4 5 6 7 extern g_val = 500 ;int main () { printf ("%d\n" , g_val); return 0 ; }
static修饰全局变量,使得这个全局变量只能在自己的源文件(.c)文件内部使用,其他源文件不能使用!
全局变量在其他源文件内可以使用是因为全局变量具有外部连接属性
被static修饰之后就变成了内部连接属性,其他源文件就不能连接到这个静态的全局变量了
常量和宏
define
define 是一个预处理 指令
用法如下两种:
define定义符号
定义常量
1 2 3 4 5 6 #define MAX 1000 int main () { return 0 ; }
define定义宏
1 2 3 4 5 6 7 8 #define ADD(X, Y) X+Y int main () { printf ("%d\n" , 4 *ADD(2 , 3 )); return 0 ; }
1 2 3 4 5 6 7 8 #define ADD(X, Y) ((X)+(Y)) int main () { printf ("%d\n" , 4 *ADD(2 , 3 )); return 0 ; }
指针
内存
进制
32位
32根地址线
通电
1/0
64位
64根地址线
^
^
地址线通电与否的电信号转换为0或1的数字信号
32位有2 32 2^{32} 2 32 个内存单元
如果 一个内存单元是一个比特
2 32 = 4 , 294 , 967 , 296 b i t 2^{32} = 4,294,967,296\ bit 2 32 = 4 , 294 , 967 , 296 bi t 比特位
4 , 294 , 967 , 296 / 8 = 536 , 870 , 912 b y t e 4,294,967,296/8 = 536,870,912\ byte 4 , 294 , 967 , 296/8 = 536 , 870 , 912 b y t e 除以8等于字节
536 , 870 , 912 / 1024 = 524 , 288 K B 536,870,912/1024 = 524,288\ KB 536 , 870 , 912/1024 = 524 , 288 K B
524 , 288 / 1024 = 512 M B 524,288/1024 = 512\ MB 524 , 288/1024 = 512 MB
512 / 1024 = 0.5 G B 512/1024 = 0.5 \ GB 512/1024 = 0.5 GB
32位内存就为0.5GB
一个内存单元是一个字节 ,然后编号
==32位内存为4GB==
1比特在32位平台是四个字节,64位平台是八个字节
为了有效使用内存,把内存划分为一个个小的内存单元,每个内存单元大小是1个字节
为了能够有效访问到内存的每个单元,就给内存单元进行编号,这些编号被称为该内存单元的地址
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 int main () { int a = 10 ; printf "(%p\n" , &a); int * pa = &a; char ch = "w" ; char * pc = &ch; return 0 ; }
1 2 3 4 5 6 7 int main () { int num = 10 ; int * p = # *p = 20 ; return 0 ; }
通过p找到num
==指针就是地址==
指针的大小
由于指针用来存放地址,地址有多大,指针就有多大,因此==指针的大小是相同的==
位数
比特
字节
32位(x86)
32bit
4byte
64位(x64)
64bit
8byte
结构体
描述复杂对象
结构体让C语言创建新的类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 struct Stu { char name[20 ]; int age; double score; } struct Book { char name[20 ]; float price; char id[30 ]; } int main () { struct Stu s = {"张三" , 20 , 85.5 }; printf ("%s %d %f\n" , s.name, s.age, s.score); struct Stu * ps = &s; printf ("%s %d %f\n" , (*ps).name, (*ps).age, (*ps).score);结果和上面等价 printf ("%s %d %f\n" , ps->name, ps->age, ps->score); return 0 ; }