一、变量的声明
数据类型 变量名;
二、变量的赋值
1.为int类型赋值
- 当给定数值超过类型范围太大,则报错。
- 如果赋值一个小数的值,则只存储整数部分。
- 如果给定数值没有超出类型范围太多,则存储随机数。
2.为float类型赋值
- 小数后面加上 f/F
- float只能精确保存有效位数不超过7位的小数。超出部分不会精确保存。
3.为double类型赋值
- 小数类型默认为double类型
- double类型的有效位数为16位,超出部分不会精确保存。
4.为char类型赋值
- char存储单个字符,用单引号引起来。
- 如果赋值多个字符则保留最后一个
- 空格也是一个字符
- 无法存储中文,C语言中一个中文占3个字节,一个char字符占1个字节。
三、printf函数的使用
1.输出纯字符
printf("双引号中的内容原样输出");
2.输出变量的值
- int类型的格式控制符
%d
%md
%0md - float类型的格式控制符
%f 或 %.nf - double类型的格式控制符
%lf 或 %.nlf - char类型的格式控制符
%c - short
%hd - long 类型格式控制符
%ld - long long 类型格式控制符
%lld - unsigned类型的格式控制符
%u
m代表1个整数,表示控制系统在打印变量时,变量输出的位宽。
当变量的值小于m位数,不足的地方在变量前面以空格补齐。
当变量的值大于等于m位,则变量实际为几位数,就显示几位数。
当m值为负数时,不足的地方则在变量后面以空格补齐。
%0md 不足的位数,用0补齐,固定用法。
%f 与%lf 默认输出小数点后面6位数字。不足6位以0补齐。
%.nf 或%.nlf
n代表数字,可以指定小数点后的位数。如果n大于类型的有效保存精度,多余部分以随机数表述。
int num = 10;
float f = 10.12f;
double d = 8.88;
char c = 'c';
printf("num=%d,float=%f,double=%lf,char=%c",num,f,d);
//若占位符存在,但缺少指定变量,则输出随机数。
//上述代码,打印为:num=10,float=10.12,double=8.88,char=x
//char的值是随机的,也可以是abcd等其他字符。
四、类型转换
实践出真知。
五、scanf函数
sacnf("格式控制符",变量的地址);
/*
接收多个数据时,在格式控制符之间可以自定义分隔符。
混合输入不可与 char混用
*/
scanf函数的缓冲区
scanf在执行时,先将用户输入的所有内容保存在缓冲区中,包括空格、回车。再从缓冲区取出数据并赋值给变量。
清空缓冲区
rewind(stdin);s
六、随机数
#include<stdlib.h>
int num = arc4random_uniform(10);//产生0-9的随机数。
七、 switch表达式
switch后面的表达式不可以是小数。
小数在内存中无法精确存储,只能无限近似存储。在比对时会出现错误。
八、goto语句
可以将cpu的执行,跳转到当前函数的其他地方继续执行。
- 先在想要跳转到的位置使用 【标签名: 】语法进行标号。
- 在需要跳转的地方使用 【goto 标签名;】。
- 标签名下一句的代码不可以是 声明变量。
九、文档注释
在函数声明的前一行,Xcode 中 Command + option +/
十、预处理指令
以#开头的代码。不以“;”符号结尾。
- 文件包含指令:#include
- 宏定义:#define
- 条件编译指令:#if
文件包含指令
#include "文件路径"
//先从当前文件的文件夹查找,如果没有再去编译器目录中查找。
#include<文件路径>
//直接查找编译器所在目录中查找,如果没有则报错。
//绝对路径:从根目录开始
//相对路径:从当前文件所在文件夹的位置。
十一、多文件开发
提供两个文件:.h后缀的文件中编写函数的声明。
.c后缀的文件中编写函数的定义。
十二、sizeof运算符
在当前系统上,计算变量、常量在内存中占用的字节数。
十三、变量的细节
变量的内存分配
高地址向低地址分配。
变量的存储
以二进制的反码形式存储。
低位存储在低字节,高位存储在高字节。
变量的地址
变量的地址是组成这个变量的低字节地址。
十四、垃圾值
局部变量回收时并不会清空变量地址中的值,而是将地址重新分配给其他变量。有可能产生垃圾值。
全局变量声明后,系统会将其地址中的数据清零。
十五、数组
数组作为参数传递时,会丢失数组的长度,因此,在函数内部使用 sizeof 运算符,无法计算长度,结果永远为8 。
函数声明时,参数列表中声明的数组类型参数,并非真实的数组。它代表着一个变量,此变量将会存放,即将作为实参传递的数组的地址。因此永远为8个字节。
十六、二维数组
在函数声明与定义时,形参的二维数组必须指定列数。
//优化写法
void test(int rows,int cols,int arr[][cols]);
十七、字符串
C语言以字符数组作为字符串存储的容器,并在后面追加 '\0’作为结束的标识。
十八、常用字符串函数
puts(char *s); //输出一个字符串
get(char *s); //从控制台获取一个字符串
strlen(字符串);//返回字符串长度。
strcmp(字符串1,字符串2);//比较两个字符串的大小,返回int,0一样大,正数1比2大,负数1比2小。比较ASCII码值
strcpy(字符串1,字符串2);//以字符串2替换字符串1. 当2的长度比1大时,系统崩溃。
strcat(字符串1,字符串2);//将2 拼接到 1的后面。如果1的长度不够会报错。
fputs(字符串,指定流);// 将字符串输出到指定字符流当中:标准输出流(控制台)/文件流
fputs(字符串,stdout); //输出到控制台
fgets(保存数据的数组,最多接收长度,指定流(stdin/文件流));//优点:安全
/*第二个参数:当接收的长度未达到指定的最大值,则会一并接收换行符。 */
/*
声明文件指针,指向磁盘中的文件。利用 fopen函数可以创建
fopen两个参数:1.文件的路径2.文件的操作模式——"w"、"r"、"a"三个值
w:write
r:read
a:append
利用fputs函数写入文件。
*/
十九、指针
指针:变量的地址。
指针变量:存储另一个变量地址的变量。只能存储与它类型相同的基本数据类型的变量地址。
指针变量声明:数据类型* 变量名。*变量名 可以为变量赋值取值。
连续声明:在变量名前填上 *。
野指针
野指针:指针变量的垃圾值,访问变量时会报错:BAD_ACCESS。
NULL值
指针变量的最佳初始化值。代表此指针变量不指向任何地址。NULL==0,也可为指针变量赋值0。
多级指针
在指针变量中,存储上一级指针变量的地址。
指针与整数的加减运算
指针变量可以与整数进行加减法,可以改变指针变量的指向。如int类型的指针,则int* p1 +3,代表着在指针 类型的值上,加3个单位的字节,及12字节。
指针变量[n] 等价于 *(指针变量+n)
存储指针的数组
数据类型* 变量名[长度]。
指针之间的减法
两个指针之间的差值/指向的普通类型的字节长度
指针指向相同类型:
代表两个指针指向的变量之间相差多少个单位变量。一般用作判断数组之间相差几个元素。
指针指向不同类型:同样的算法,但是没有意义。
指向函数的指针
返回值类型 (*指针名)(参数列表)。
函数名代表函数的地址
二十、内存分区
栈(存放局部变量)、堆、BSS段(已声明的未初始化的全局变量和静态变量)、数据段\常量区(已经初始化的全局变量和静态变量)、代码段(存储程序的代码/指令)
字符数组存储字符串与字符指针存储数组的区别
字符数组内的字符存储在栈中。指针指向的字符串是存在常量区中。
二十一、字符串排序
实践出真知。
二十二、const
const 修饰指针时:
const int* p = #//无法通过指针,修改num的值
int* const p1 = # //无法修改p1的值。
int const * p1 = # //都无法修改。
无法通过指针修改指针指向的变量的值。
二十三、内存管理
// void* malloc(size_t) //申请连续的字节空间,返回第一个申请的字节地址
/*
申请的字节地址由低到高分配。
多次申请的地址之间不是连续的地址空间。
申请的地址空间中可能有垃圾值。
申请失败时返回NULL值。
使用完用 使用free(指针)函数,释放内存。
*/
// calloc(多少个单位,每个单位所占字节);//申请的字节空间自动清零,不存在垃圾值。
// realloc(需要扩容的指针,扩容的大小 );//自动扩容,若扩容的地址不够,则重新寻找足够的空间。并将原数据拷贝过来。
//在stdlib.h中
二十四、结构体
二十五、枚举
每个枚举项都有对应的整型值。每个枚举变量占四个字节。
使用规范:枚举的值的名称都以枚举类型开头。
二十六、typedef
为已经存在的数据类型 取别名。
//如:
typedef char* string;
二十七、宏定义,条件编译指令
宏定义
为一段c代码定义一个标识,后面可以直接通过名字使用。
#define 宏名 宏值
程序在预编译时,会将宏名替换为宏值。
#undef 宏名 此代码后宏被不许访问
带参数的宏
宏名中的参数可以在宏值中直接使用。
条件编译指令
#if 条件
//代码
#elif 条件
//代码
#endif
//当条件成立时,中间的c代码才成立
//条件只能是宏。
#ifdef 宏名 // 或 #ifndef 宏名
//代码
#endif
//如果(没有)定义了宏,则编译
二十八、static,extern
static修饰局部变量
用static声明变量,会将变量声明在常量区。
extern不能修饰局部变量。
static、extern修饰全局变量/函数
将全局变量定义在模块中,需要使用 static 或extern 修饰。
extern修饰的全局变量可以跨模块访问。
函数的默认修饰符是。extern