C语言
1. C语言基本结构
// 文件结尾.c
// 预处理器指令
#include <stdio.h>
// 主函数
int main()
{
// 注释
/* 我的第一个 C 程序 */
// 调用函数
printf("Hello, World! \n");
return 0;
}
2. 基本语法
1. 关键字
C99 新增关键字
C11 新增关键字
3. 数据类型、变量、常量
1. 整数类型
2. 浮点型
3. 变量声明
除了extern关键字比如extern int i;这种为声明不是定义,其他比如int i;都为声明与定义
4. 输出语句
// 输入函数
scanf("%d", &number);
// 输出函数
printf("result 为: %d",result);
// 一个%d对应一个实惨,用","后面接收参数,顺序接收
// 浮点型为%f
5. 强制转换
(数据类型) (表达式)
字节小的可以向字节大的自动转换,但字节大的不能向字节小的自动转换
char可以转换为int,int可以转换为double,char可以转换为double。但是不可以反向。
6. 常量
C语言中定义常量方式
- 使用 #define 预处理器。
#define identifier value
#define LENGTH 10 - const
const type variable = value;
const int LENGTH = 10;
7. 算术运算符
存储类定义 C 程序中变量/函数的范围(可见性)和生命周期。
1. 基本运算符
2. 赋值运算符
普通:=
复杂:例如+=、-=、*=、/=、%=
3. 关系运算符
4. 逻辑运算符
5. 三目运算符
表达式1 ? 表达式2 : 表达式3;
6. sizeof运算符
sizeof可以用来计算一个变量或常量、数据类型所占的内存字节数
7. 逗号运算符
3. 存储类
1. auto 存储类是所有局部变量默认的存储类。
{
int mount;
auto int month;
}
2. register 存储类
定义存储在寄存器中的局部变量
{
register int miles;
}
3. static 存储类
static 存储类指示编译器在程序的生命周期内保持局部变量的存在,而不需要在每次它进入和离开作用域时进行创建和销毁。
static int count=10;
4. extern 存储类
extern 存储类用于提供一个全局变量的引用,全局变量对所有的程序文件都是可见的。
extern void write_extern();
extern int count;
4. 循环、分支结构
1. while
while ( 循环控制条件 ) {
循环体中的语句;
能够让循环结束的语句;
…
}
2. do…while
do {
循环体中的语句;
能够让循环结束的语句;
…
} while (循环控制条件 );
3. for
for(初始化表达式;循环条件表达式;循环后的操作表达式) {
循环体中的语句;
}
4. 循环嵌套
循环结构的循环体中存在其他的循环结构,我们称之为循环嵌套
注意: 一般循环嵌套不超过三层
外循环执行的次数 * 内循环执行的次数就是内循环总共执行的次数
5. 循环控制语句
6. 分支结构
if if-else if-else-if
5. 函数
1. 函数概念
1. 定义函数
return_type function_name( parameter list )
{
body of the function
}
2. 函数声明
return_type function_name( parameter list );
3. 调用函数
4. 函数参数
6. 作用域规则
1. 局部变量
在某个函数或块的内部声明的变量称为局部变量。
2. 全局变量
全局变量是定义在函数外部,通常是在程序的顶部。
3. 形式参数
函数的参数,形式参数,被当作该函数内的局部变量,如果与全局变量同名它们会优先使用。
7. 数组
1. 数组基本概念
语法:type arrayName [ arraySize ];
double balance[10];
// 指定数组长度
double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};
// 数组长度默认为元素个数
double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};
// 数组赋值
balance[4] = 50.0;
2. 多维数组
多维数组声明:type name[size1][size2]…[sizeN];
int threedim[5][10][4];
祥讲二维数组
type arrayName [ x ][ y ];
// 三行四列
int x[3][4];
// 初始化二维数组
int a[3][4] = {
{0, 1, 2, 3} , /* 初始化索引号为 0 的行 */
{4, 5, 6, 7} , /* 初始化索引号为 1 的行 */
{8, 9, 10, 11} /* 初始化索引号为 2 的行 */
};
int a[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};
// 访问二维数组
int val = a[2][3];
3. 数组与函数
1. 传递数组给函数
方式 1
形式参数是一个指针
void myFunction(int *param)
{
.
.
.
}
方式 2
形式参数是一个已定义大小的数组:
void myFunction(int param[10])
{
.
.
.
}
方式 3
形式参数是一个未定义大小的数组:
void myFunction(int param[])
{
.
.
.
}
2. 从函数返回数组
允许函数返回数组,此时返回的是数组的地址
4. 指向数组的指针
数组名是一个指向数组中第一个元素的常量指针。
// balance 是一个指向 &balance[0] 的指针,即数组 balance 的第一个元素的地址。
double balance[50];
// 把 p 赋值为 balance 的第一个元素的地址
double *p;
double balance[10];
p = balance;
使用数组名作为常量指针是合法的
*(balance + 4) 是一种访问 balance[4] 数据的合法方式
一旦把第一个元素的地址存储在 p 中,就可以使用 p、(p+1)、*(p+2) 等来访问数组元素。
5. 数组长度计算方法
数组的长度 = 数组占用的总字节数 / 数组元素(类型)占用的字节数
int ages[4] = {19, 22, 33, 13};
int length = sizeof(ages)/sizeof(int);
printf("length = %d", length);
// 输出结果: 4
8. enum(枚举)
语法
// 默认从0开始
enum 枚举名 {枚举元素1,枚举元素2,……};
// 从1开始自增
enum DAY
{
MON=1, TUE, WED, THU, FRI, SAT, SUN
};
// 0 3 4 5
enum season {spring, summer=3, autumn, winter};
枚举变量的定义
// 1、先定义枚举类型,再定义枚举变量
enum DAY
{
MON=1, TUE, WED, THU, FRI, SAT, SUN
};
enum DAY day;
// 2、定义枚举类型的同时定义枚举变量
enum DAY
{
MON=1, TUE, WED, THU, FRI, SAT, SUN
} day;
// 省略枚举名称,直接定义枚举变量
enum
{
MON=1, TUE, WED, THU, FRI, SAT, SUN
} day;
将整数转换为枚举
enum day
{
saturday,
sunday,
monday,
tuesday,
wednesday,
thursday,
friday
} workday;
int a = 1;
enum day weekend;
weekend = ( enum day ) a; //类型转换
9. 指针
1. 变量内存地址
每一个变量都有一个内存位置,每一个内存位置都定义了可使用 & 运算符访问的地址,它表示了在内存中的一个地址
#include <stdio.h>
int main ()
{
int var_runoob = 10;
int *p; // 定义指针变量
p = &var_runoob;
// var_runoob 变量的地址: 0x7ffeeaae08d8
printf("var_runoob 变量的地址: %p\n", p);
return 0;
}
2. 什么是指针?
指针也就是内存地址,指针变量是用来存放内存地址的变量。就像其他变量或常量一样,必须在使用指针存储其他变量地址之前,对其进行声明。指针变量声明的一般形式为:
type *var_name;
不同数据类型的指针之间唯一的不同是,指针所指向的变量或常量的数据类型不同。
3. 如何使用指针?
int var = 20; /* 实际变量的声明 */
int *ip; /* 指针变量的声明 */
ip = &var; /* 在指针变量中存储 var 的地址 */
指针没有初始化里面是一个垃圾值,这是一个野指针
野指针可能会导致程序崩溃
野指针访问你不该访问数据
所以指针必须初始化才可以访问其所指向存储区域
4. C 中的 NULL 指针
赋为 NULL 值的指针被称为空指针。
int *ptr = NULL;
5. C 指针的算术运算
可以对指针进行四种算术运算:++、–、+、-。
假设 ptr 是一个指向地址 1000 的整型指针,是一个 32 位的整数
// 一次移动四个字节:1004
ptr++
·指针的每一次递增,它其实会指向下一个元素的存储单元。
·指针的每一次递减,它都会指向前一个元素的存储单元。
·指针在递增和递减时跳跃的字节数取决于指针所指向变量数据类型长度,比如 int 就是 4 个字节。
6. 指针数组
一个变量有地址,一个数组包含若干元素,每个数组元素也有相应的地址, 指针变量也可以保存数组元素的地址
只要一个指针变量保存了数组元素的地址, 我们就称之为数组元素指针
下面是一个指向整数的指针数组的声明:
// 把 ptr 声明为一个数组,由 MAX 个整数指针组成
int *ptr[MAX];
#include <stdio.h>
const int MAX = 3;
int main ()
{
int var[] = {10, 100, 200};
int i, *ptr[MAX];
for ( i = 0; i < MAX; i++)
{
ptr[i] = &var[i]; /* 赋值为整数的地址 */
}
for ( i = 0; i < MAX; i++)
{
printf("Value of var[%d] = %d\n", i, *ptr[i] );
}
return 0;
}
7. 二级指针
1. 如果一个指针变量存放的又是另一个指针变量的地址,则称这个指针变量为指向指针的指针变量。也称为“二级指针”
char c = 'a';
char *cp;
cp = &c;
char **cp2;
cp2 = &cp;
printf("c = %c", **cp2);
2. 多级指针的取值规则
int ***m1; //取值***m1
int *****m2; //取值*****m2