一、变量的声明
数据类型 变量名;
二、变量的赋值
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);
四、类型转换
实践出真知。
五、scanf函数
sacnf("格式控制符",变量的地址);
scanf函数的缓冲区
scanf在执行时,先将用户输入的所有内容保存在缓冲区中,包括空格、回车。再从缓冲区取出数据并赋值给变量。
清空缓冲区
rewind(stdin);s
六、随机数
#include<stdlib.h>
int num = arc4random_uniform(10);
七、 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);
strcpy(字符串1,字符串2);
strcat(字符串1,字符串2);
fputs(字符串,指定流);
fputs(字符串,stdout);
fgets(保存数据的数组,最多接收长度,指定流(stdin/文件流));
十九、指针
指针:变量的地址。 指针变量:存储另一个变量地址的变量。只能存储与它类型相同的基本数据类型的变量地址。 指针变量声明:数据类型* 变量名。*变量名 可以为变量赋值取值。 连续声明:在变量名前填上 *。
野指针
野指针:指针变量的垃圾值,访问变量时会报错:BAD_ACCESS。
NULL值
指针变量的最佳初始化值。代表此指针变量不指向任何地址。NULL==0,也可为指针变量赋值0。
多级指针
在指针变量中,存储上一级指针变量的地址。
指针与整数的加减运算
指针变量可以与整数进行加减法,可以改变指针变量的指向。如int类型的指针,则int* p1 +3,代表着在指针 类型的值上,加3个单位的字节,及12字节。
指针变量[n] 等价于 *(指针变量+n)
存储指针的数组
数据类型* 变量名[长度]。
指针之间的减法
两个指针之间的差值/指向的普通类型的字节长度 指针指向相同类型: 代表两个指针指向的变量之间相差多少个单位变量。一般用作判断数组之间相差几个元素。 指针指向不同类型:同样的算法,但是没有意义。
指向函数的指针
返回值类型 (*指针名)(参数列表)。 函数名代表函数的地址
二十、内存分区
栈(存放局部变量)、堆、BSS段(已声明的未初始化的全局变量和静态变量)、数据段\常量区(已经初始化的全局变量和静态变量)、代码段(存储程序的代码/指令)
字符数组存储字符串与字符指针存储数组的区别
字符数组内的字符存储在栈中。指针指向的字符串是存在常量区中。
二十一、字符串排序
实践出真知。
二十二、const
const 修饰指针时:
const int* p = #
int* const p1 = #
int const * p1 = #
无法通过指针修改指针指向的变量的值。
二十三、内存管理
二十四、结构体
二十五、枚举
每个枚举项都有对应的整型值。每个枚举变量占四个字节。
使用规范:枚举的值的名称都以枚举类型开头。
二十六、typedef
为已经存在的数据类型 取别名。
typedef char* string;
二十七、宏定义,条件编译指令
宏定义
为一段c代码定义一个标识,后面可以直接通过名字使用。 #define 宏名 宏值 程序在预编译时,会将宏名替换为宏值。 #undef 宏名 此代码后宏被不许访问
带参数的宏
宏名中的参数可以在宏值中直接使用。
条件编译指令
#if 条件
#elif 条件
#endif
#ifdef 宏名
#endif
二十八、static,extern
static修饰局部变量
用static声明变量,会将变量声明在常量区。 extern不能修饰局部变量。
static、extern修饰全局变量/函数
将全局变量定义在模块中,需要使用 static 或extern 修饰。 extern修饰的全局变量可以跨模块访问。 函数的默认修饰符是。extern
|