写于2021.6.15。
此文为本人浅层次学完C语言的一个整理与记录。
所记内容,都是基础中的基础,需牢记于心。
目录
一:数据类型
数据类型 | 32位编译器 | 64位编译器 |
Char | 1 | 1 |
Short | 2 | 2 |
Int | 4 | 4 |
Long | 4 | 8 |
Long long | 8 | 8 |
Float | 4 | 4 |
double | 8 | 8 |
二:变量、常量
1.变量
局部变量 | 全局变量 | |
作用域 | 局部范围 | 整个工程 |
生命周期 | 局部范围 | 整个程序 |
2.常量
字面常量、const修饰的常量、
#define修饰的标识符常量、枚举常量(放在开头,不要加分号)
三:字符串
字符串是以’\0’结束
Strlen:获取字符串有效字符个数,不算’\0\
Sizeof:获取数组总大小
四:转义字符
\n:换行(不一定到下一行行首)
\r:回车
\t:水平制表符
\v:垂直制表符
\’:字符常量’
\’’:双引号
\a:警告字符
\b:退格符
\f:进纸符
\ddd:八进制
\xdd:十六进制
五:选择结构
0表示假,非0表示真
1.if…else语句
if(条件)
语句;
2.switch语句
每一个case记得加break,每个switch语句都放一条default子句
switch(整型表达式)
{
case1;
break;
case2:
break’
default:
break;
}
六:循环语句
1.while循环
while(表达式)
循环语句;
Break 语句在while循环中:break是用来永久终止循环的
int main()
{
int i = 1;
while (i <= 10)
{
if (i == 5)
break;
printf("%d", i);
i = i + 1;
}
return 0;
}
结果:1234
continue是用于终止本次循环的,即本次循环后面的代码不会执行,直接跳转到while语句的判断部分
2.for循环
3.do while
循环至少执行一次
七::函数
- 库函数:使用库函数,必须包含#include对应的头文件
- 自定义函数
函数的调用:传值调用,传址调用
函数的参数:实际参数,形式参数
函数的嵌套调用:函数和函数之间有机组成的
函数的链式调用:把一个函数的返回值作为另一个函数的参数
函数的声明与定义:先声明后定义,函数的定义是指函数的具体实现
test.h:放函数的声明
test.c:放函数的实现
函数递归两个必要条件:
1.存在限制条件,当满足这个限制条件时,函数不在继续
2.每次递归调用后越来越接近这个限制条件
例:
void Print(int n)
{
if (n > 9)
{
print(n / 10);
}
printf("%d ", n % 10);
}
int main()
{
int num = 1234;
Print(num);
return 0;
}
例:n的阶乘
int factorial(int n)
{
if (n <= 1)
return 1;
else
return n*factorial(n - 1);
}
int main()
{
int num = 4;
factorial(num);
printf("%d", factorial(num));
return 0;
}
当参数过大时,会报错。
原因:系统分配给程序的栈空间是有限的,如果出现了死循环或者死递归,那么就可能一直开辟栈空间,导致空间溢出,即栈溢出。
解决办法:1.递归写成非递归2.使用static对象代替nonstatic
八:数组
[]中给一个常量,不可为变量
注意区分:
char arr1[] = "abc"; 长度4
char arr2[3] = {'a','b','c'}; 长度3
数组在内存中是连续存放的
- 一维数组
#include<stdio.h>
int main()
{
int arr[] = { 1, 2, 3, 4, 5 };
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);//只适用于数组在哪定义在哪使用
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
2.二维数组
int main()
{
int arr[2][3] = { 1, 2, 3, 4, 5,6 };
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
printf("%d ", arr[i][j]);
}
}
return 0;
}
arr[2][4]=4 二维数组本身是一块连续的内存。
Sizeof(数组名):sizeof(arr)代表整个数组的大小
int arr[10] = {0}; printf("%d\n", sizeof(arr));//输出40
&arr:代表数组的地址
除了以上两种情况,所有数组名都代表数组首元素的地址。
九:操作符
1.算数操作符:
+ - * / % (%两边必须为整数)
2.移位操作符:
<<左移操作符:右边补0
>>右移操作符:逻辑移位:左边补0,右边丢弃 算数移位:左边补符号位
3.位操作符
&按位与:同为1才是1
|按位或:有1即为1
^按位异或:一样的位上为0,不一样位上为1(0^任何数即为任何数)
4.赋值操作符
=
复合赋值符:+= -= *= %=
5.单目操作符
(一般只与一个有关)
!逻辑反 -负数 +正数 &取地址 sizeof操作符的类型长度
~对一个数的二进制按位取反 --前置后置-- ++前置后置++
*间接访问操作符(解引用操作符)
(类型)强制类型操作符
6.关系操作符
> >= < <= != ==
7.逻辑操作符
&&逻辑与(表达式1假就不会执行表达式2)
||逻辑或(表达式1真就不会执行表达式2)
8.条件操作符
exp1?exp2:exp3
即if(a>5) b=3;
else b=-3;
9.逗号表达式
逗号隔开的多个表达式,从左到右依次执行,整个表达式的结果就是最后一个表达式的结果
10.访问一个结构的成员
. 结构体.成员名
->结构体指针->成员名
十:关键字
typedef:重命名
static:静态
静态局部变量:生命周期变为整个程序
静态全局变量:作用域变为本源文件
静态函数:作用域变为本源文件,不可在其它文件使用
(这里只是简单概述记录,不完全,更多内容后期)
十一:指针
1.基础概念
32位平台:4个字节
64位平台:8个字节
指针:将地址形象化为指针,通过它能找到以它为地址的内存单元。
指针是个变量,存放内存单元的地址。
指针的类型决定了指针向前或向后走一步有多大。
野指针:指针指向的位置是不可知的(随机的,不正确的,没有明确限制的)
2.指针和数组
允许指向数组元素的指针与指向数组最后一个元素的那个内存位置指针比较,但不允许与指向第一个元素之前的指针进行比较
数组名表示的是数组首元素的地址。 Int *p=arr(指针存放数组首元素的地址)
通过指针来访问数组:
#include<stdio.h>
int main()
{
int arr[] = { 1, 2, 3, 4, 5 };
int *p = arr;
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d", *(p + i));
}
return 0;
}
3.指针数组
指针数组是数组,存放指针的数组。
Int *arr[5] arr是一个数组,有5个元素,每个元素是一个指针
十二:结构体
结构体成员可以是标量,数组,指针,甚至其他结构体
结构体成员的访问:
操作符. 结构体.成员名
指针(*ps).name 或者 ps->name
结构体传参时要传结构体的地址。
typedef struct Stu
{
char name[20];
int age;
char sex[5];
char id[20];
};Stu
有typedef:直接变成一种类型
无typedef:是个变量