C语⾔:(⾯向过程)计算机语⾔,⼈和计算机交流的⼀种语⾔
擅⻓底层应⽤开发 电脑硬件
例:0101 - ADD
0000 - JMP
#include
2 // stdio - 标准输入输出
3
4 // main函数是程序的入口
5 // 一个工程中main函数有且仅有一个
6 int main()
7 {
8 // 库函数 - 打印函数 - 输出函数
9 printf("Hello World!\n");
10 return 0;
11 }
char - 字符数据类型
short - 短整型
int - 整形
long - 长整型
long long - 更⻓的整形
float - 单精度浮点数
double - 双精度浮点数 --> 科学计数法,⼩数点可以浮动
#include
int main()
{
printf("%d\n", sizeof(char));
printf("%d\n", sizeof(short));
printf("%d\n", sizeof(int));
printf("%d\n", sizeof(long));
printf("%d\n", sizeof(long long));
printf("%d\n", sizeof(float));
printf("%d\n", sizeof(double));
return 0;
}
bit - 比特
byte - 字节 = 8bit
kb = 1024byte
mb = 1024kb
gb = 1024mb
tb = 1024gb
pb = 1024tb
整数:为了选择适合范围的整形类型。
浮点数:选择更加符合精度的类型;为了丰富地表达⽣活中的各种值。
sizeof(long) >= sizeof(int) long可能是4或8
#include
int main()
{
char ch = 'e';
printf("%c\n", ch);
printf("%d\n", ch);
return 0;
}
每个字符对应⼀个值 转化为⼆进制存进
如:
a - 97
b - 98
A - 65
B - 6
age是变量 可以被改变
#include
int main()
{
short age = 10;
age = 11;
printf("%d\n", age);
return 0;
}
局部变量
全局变量
#include
int g = 100; // 全局变量
int main()
{
int a = 10; // 局部变量 大括号内部
return 0;
}
#include
int main()
{
// 2个整数相加
int num1 = 0;
int num2 = 0;
// 输入
scanf_s("%d%d", &num1, &num2);
int sum = num1 + num2;
// 输出
printf("%d\n", sum);
return 0;
}
局部变量所在的局部范围
#include
int main()
{
int b = 100;
{
int a = 10;
printf("a = %d\n", a); // 10
printf("b = %d\n", b); // 100
}
printf("b = %d\n", b); // 100
return 0;
}
整个工程都可使用
// test.c
int g_val = 2021;
// main.c
#include
// 声明外部变量
extern int g_val;
int main()
{
printf("%d\n", g_val);
return 0;
}
局部变量的生命周期:进入局部变量的范围,生命周期开始,出局部变量生命周期结束。
全局变量的生命周期:程序的生命周期,
int main()
{
// 字面常量
3.14; // 浮点型字面常量
}
一个变量不能被改变我们就说具有常属性 - 不能被改变的属性
int main()
{
const int n = 100;
// int arr[n] = { 0 }; // err
}
#include
#define MAX 100
int main()
{
int a = MAX;
printf("a = %d\n", a); // 100
return 0;
}
可用于数组:
int arr[MAX] = {0};
枚举:一一列举
#include
// enum - 枚举关键字
// enum Sex - 枚举类型
enum Sex
{
// 枚举的可能取值 - 枚举常量
MALE,
FEMALE,
SECRET
};
int main()
{
enum Sex s = MALE; // 表示性别的变量
printf("%d\n", MALE);
printf("%d\n", FEMALE);
printf("%d\n", SECRET);
// 枚举常量默认从0开始递增 0 1 2
}
赋初值可以更改,枚举常量不能改
#include
enum Sex
{
MALE = 3,
FEMALE = 7,
SECRET
};
int main()
{
// MALE = 4; // err
}
若编译器支持C99标准变长允许使用变量
#include
int main()
{
const int n = 3;
int arr[n] = { 0, 1, 2 };
printf("%d", arr[0]);
printf("%d", arr[1]);
printf("%d", arr[2]);
return 0;
}
char ch[10] = "abcdef"; // 用abcdef初始化数组
其中有七个字符abcdef\0,剩下三个字符默认放\0 --> abcdef\0\0\0\0
printf("%s\n", ch);
两种形式,用字符串打印时,f后隐藏\0;
而单个字符打印时,没有\0,此时要添加’\0’,否则会出现乱码
#include
int main()
{
char ch1[] = "abcdef";
printf("%d\n", strlen(ch1)); // 6
// stelen 库函数 - 求字符串长度的 \0是字符串结束标志 不算长度
char ch2[] = { 'a', 'b', 'c', 'd', 'e', 'f', '\0' };
printf("%d\n", strlen(ch2)); // 6
return 0;
}
例如\t --> 输出结果为c: est est.c
若要打印,改为c:\test\test.c
转义字符 | 释义 |
---|---|
\?’ | 在书写连续多个问号时使用,防止他们被解析成三字母词 |
\’ | 用于表示字符常量 |
\‘’ | 用于表示一个字符串内部的双引号 |
\\ | 用于表示一个反斜杠,防止它被解释为一个转义序列符 |
\a | 警告字符,蜂鸣 |
\b | 退格符 |
\f | 进纸符 |
\n | 换行 |
\r | 回车 |
\t | 水平制表符 |
\v | 垂直制表符 |
\ddd | ddd表示1~3个八进制的数字。如:\130X |
\xdd | dd表示2个十六进制数字。如:\x30 0 |
打印单引号
printf("%c", '\'');
??) — ]
??( — [
// 若支持三字母词, 要加上转义字符
int main()
{
// printf("%s\n", "????)");
printf("%s\n", "??\?\?)");
return 0;
}
// 十进制123 – 1* 10^2 + 2* 10^1 + 3* 10^0 = 100+20+3 = 123
// 八进制065 – 0* 8^2 + 6* 8^1 +5* 8^0 = 48+5 = 53
// 8进制的065转换10进制是:53
// \ddd - ddd的8进制数字转成10进制后的值,作为ASCII值所代表的字符
// 53对应的字符是5
// 16进制51 – 5* 16^1 + 1* 16^0 = 80+1 = 81
// 81对应得ASCII码值是Q
#include
int main()
{
printf("%d\n", strlen("abcdef"));
printf("%d\n", strlen("c:\test\328\test.c"));
return 0;
}
C语言风格注释缺陷:不能嵌套注释
C++风格注释:可以一行也可以注释多行
int main()
{
// C++注释风格
// 创建整型变量a,并复制10
int a = 10;
/* C语言注释风格
int b = 20;
*/
return 0;
}
#include
int Add(int x, int y)
{
int z = 0;
z = x + y;
return z;
}
int main()
{
int num1 = 0;
int num2 = 0;
int sum = 0;
scanf_s("%d %d", &num1, &num2);
sum = Add(num1, num2);
printf("%d\n", sum);
return 0;
}
数组:一种相同类型元素的集合
访问数组元素,从0开始。例打印6
int main()
{
int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
printf("%d\n", arr[5]);
return 0;
}
加减乘除取模 + - * / %
例:除法
% - 取模(余) 得到的是整除之后的余数
#include
int main()
{
int a = 7 % 2; // 3……1
printf("%d\n", a);
return 0;
}
// & - 按位与 按2进制
// ^ - 按位异或
// | - 按位或
& 只要有0就为0,两个都为1才为1
^ 相同为0,相异为1
| 只要有1个真就为真
int main()
{
int a = 10; // 创建变量a,并初始化为10
a = 20; // 赋值
a += 10; // 复合赋值
// 复合赋值符 += -= *= /= &= ^= |= >>= <<=
return 0;
}
// ! 逻辑反操作
// - 负值 + 正值
// sizeof 操作数的类型长度
// ~ 对一个数的二进制按位取反
// 前置、后置-- ++ 前置、后置++
// * 间接访问操作符(解引用操作符)
// (类型) 强制类型转换
单目操作符:只有一个操作数
a和b是+的两个操作数 +是双目操作符
真和假
0为假 非0为真
int main()
{
int a= 10;
printf("%d\n", !a); // 0
// 10是真 变为假0
}
int main()
{
int a = 10;
int b = -a; // 负值
}
整数在内存中存储的时候,存储是二进制
一个整数的二进制表示有3中形式:
原码 反码 补码
正的整数:原反补相同
负的整数:要计算
原码的符号位不变,其它位按位取反得反码。反码的二进制序列+1得补码
有符号的整数,最高位是0,表示正数
1,表示负数
内存中存储整数的时候,存储的是二进制的补码
计算的时候才用的也是补码
前置++
先++,后使用
int main()
{
int a = 2;
// a++; // a=a+1 a+=1
int c = ++a;
printf("c=%d\n",c); // 3
printf("a=%d\n",a); // 3
return 0;
}
后置++
先使用,后++
#include
int main()
{
int a = 2;
int c = a++;
printf("c=%d\n", c); // 2
printf("a=%d\n", a); // 3
return 0;
}
int main()
{
int a = (int)3.14; // 3
// 尽量避免
return 0;
}
“ > >= < <= != ”用于测试“不相等”
== 用于测试“相等”
&& - 逻辑与 - 并且 两个都满足
|| - 逻辑或 - 或者 只要有一个满足
exp1 ? exp2 : exp3;
先执行exp1;若为真,执行exp2为整个表达式的结果;若为假,执行exp3为整个表达式的结果
#include
int main()
{
int a = 10;
int b = 0;
if (5 == a)
{
b = -6;
}
else
{
b = 6;
}
b = ((a == 5) ? -6 : 6);
return 0;
}
// exp1, exp2, exp3, …expn
// 逗号表达式会从左向右依次计算
// 整个逗号表达式的结果是最后一个表达式的结果
int main()
{
int a = 0;
int b = 3;
int c = -1;
int d = (a = b - 5, b = a + c, c = a + b, c -= 5);
printf("%d\n", d); // -10
return 0;
}
// 常用关键字
// auto break停止,中断(用于循环) case char const常属性 contine继续(用于循环)
// default do double else enum枚举
// extern声明外部符号 float单精度浮点数 for goto语句 if int long
// register寄存器关键字 return返回函数 short signed有符号的 sizeof计算大小
// static静态的 struct结构体关键字 switch typedef类型定义/重定义 union联合体/共用体
// unsigned void空 volatile(Linux中-易变的) while循环
// 不能与符号名冲突
//auto int a = 10; // 局部变量-自动变量 auto自动省略
// typedef - 类型定义/类型重定义 unsigned int u_int
//auto int a = 10; // 局部变量-自动变量
int 定义的变量是有符号的 signed int - signed省略
无符号:unsigned ---unsigned int num = 1;无符号数
// unsigned int u_int
// register int num = 10; // 建议把num定义成寄存器变量,编译器自行判断
// & num; // err 取地址取的是内存 寄存器独立于内存
// 寄存器是存储空间,在电脑上一般是集成到CPU上的,和内存是独立的存储空间
// 寄存器 高度缓存 内存 硬盘 网盘 – 速度由高到低
static在C语言中的用法:
修饰局部变量
修试全局变量
修饰函数
局部变量 进创建 出销毁
static 修饰局部变量
改变了变量的生命周期;不影响作用域,因为还是局部变量
加上extern 就可以使用g_val变量
// add.c
int g_val = 2021;
// test.c
extern int g_val
int main()
{
printf("%d\n", g_val);
return 0;
}
如果加上static 就无法使用
默认一个全局变量是具有【外部】链接属性的
而如果全局变量被static修饰,全局变量的外部属性变成了内部链接属性,这个时候全局变量只能在本源文件内部使用
其他源文件无法链接到,也无法使用!
// 如果中添加static,无法使用
// 函数是具有外部链接属性,如果被static修饰,外部链接属性就变成了内部连接属性
// 函数只能在自己的源文件内部使用,不能在其他源文件内部使用!
#define NUM 100
int main()
{
printf("%d\n", NUM);
return 0;
}
MAX-宏名 (X, Y)-宏变量 (X>Y?X:Y)-宏主体
宏作用:替换
宏变量没有类型
#define MAX(X, Y) (X>Y?X:Y)
int main()
{
int a = 10;
int b = 20;
int c = MAX(a, b);
// int c = (a > b ? a : b);
printf("%d\n", c); // 20
return 0;
}
每个内存单元都有编号
32位
32位地址线/数据线
通电转换为数字信号有正负电
正电是1负电是0
00000000000000000000000000000000
00000000000000000000000000000001
00000000000000000000000000000010
…
11111111111111111111111111111111
32个二进制序列
bit *8
byte *1024
kb
mb
gb
tb
pb
2^32bit =
4,294,967,296bit/8 = 536,870,912byte
= 524,288kb = 512MB = 0.5GB
如果一个内存单元是一个bit
char - 1byte - 8bit - 8个地址
int - 4byte - 32bit - 32个地址
short - 2byte - 16bit - 16个地址
太浪费了
%s字符串 %c字符 %d整形 %p地址
int main()
{
int a = 10; // 向内存申请4个字节空间,里面存放10
printf("%p\n", &a); // & - 取地址操作符 单目
int* pa = &a;
// pa 是一个存放地址的变量,称为指针变量
// int* 指针变量的类型
char ch = 'w';
char* pa = &ch;
return 0;
}
int main()
{
char ch = 'w';
char* pc = &ch;
*pc = 'b';
printf("%c\n", ch);
return 0;
}
总结:
指针大小在32位平台是4个字节,64位平台是8个字节
0000000000000000000000000000000000000
struct Student
{
char name[20];
int age;
char sex[5];
char id[12];
};
int main()
{
struct Student s1 = { "张三", 20, "男", "1905468128" };
struct Student s1 = { "李四", 19, "女", "1904927125" };
return 0;
}
struct Book
{
char name[20];
int price;
char auther;
};
int main()
{
struct Book b1 = { "百年孤独", 55, "马尔克斯" };
struct Book* pb = &b1;
printf("%s %d %s\n", (*pb).name, (*pb).price, (*pb).author);
printf("%s %d %s\n", pb->name, pb->price, pb->author);
// . 结构体变量.成员名
// -> 结构体->成员名
return 0;
}
Visual Studio: 面向软件开发人员和 Teams 的 IDE 和代码编辑器