c 总结
C-总结
#pragma mark - 第一章:C基础
void func1();
void func1()
{
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int a = 030; // 以0开头得数是八进制的数,计算的时候要换算成10进制进行计算
int b = a * 10;
printf("%d", b); // 此时打印出来的结果是240
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 注释的嵌套问题
// 1. 单行注释可以嵌套单行注释
// 2. 单行注释可以嵌套多行注释
// 3. 多行注释可以嵌套单行注释
// 4. 多行注释不可以嵌套多行注释(注意项)
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int c = 10;
c++;
++c;
// 注意递增、递减运算符在前在后的两种情况,一种是返回新值,一种是返回旧值,还需要注意,不管是返回新值还是返回旧值,运算完之后,c的值都会发生改变
}
#pragma mark - 第二章:分支结构
void func2();
void func2()
{
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int a = 10, b = 20;
BOOL result = (a++ > 100 && b++ > 20);
printf("result = %d a = %d b = %d\n", result, a, b);
// 结果如下,注意 -短路- 情况,逻辑或‘||’也是一样的
// result = 0 a = 11 b = 20
// '&&':一假即假,全真则真
// '||':一真即真,全假则假
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
enum Season {
spring,
summer = 4,
autumn,
winter
};
printf("autumn = %d", autumn);
// 结果: 需要注意的是,枚举变量的值是上一个值 +1
// autumn = 5
}
#pragma mark - 第三章:循环结构
void func3();
void func3()
{
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 随机数公式:随机出范围在a~b之间的随机数:arc4random() % (b - a + 1) + a;
int a = 10, b = 100;
int random = arc4random() % (b - a + 1) + a;
printf("random = %d\n", random);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// break; 关键字,跳出本层循环,后面的东西全都不再执行
// continue; 关键字,跳出本次循环,本次循环后面的东西不再执行,下一次继续执行
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for (; ; ) {
printf("for循环中的任何条件都可以缺失,只是这种写法会造成死循环\n");
}
}
#pragma mark - 第四章:数组
void func4();
void func4()
{
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int a[5] = { 2, 7, 4, 3, 6 };
int b[5] = { 2, 7, 4 };
int c[5] = { 0 };
int d[] = { 2, 7, 4, 3, 6 };
// 注意这些的区别,个数不写的话会自动计算,写了个数不能超,不写的默认是0
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int count = 10;
// int arr[count] = {0}; // 注意,这种写法是错误的,变量不可以放在数组定义的中括号中,可以是常量和宏定义
int arr[10] = {0};
#define kArrayCount 10
int arr2[kArrayCount] = {0};
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 系统不会检测数组下标是否越界,所以我们程序员一定要注意数组下标越界的问题
// 数组是一个整体,不能直接参加运算,只能对单个元素进行处理,通常用到数组的地方都会用到循环
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 冒泡排序写法
int array[] = {10, 23, 53, 123, 3, 53, 23, 123, 53};
int arrayCount = sizeof(array) / sizeof(int);
// 双层循环
for (int i = 0; i < arrayCount - 1; i++) {
for (int j = 0; j < arrayCount - 1 - i; j++) {
if (array[j] > array[j + 1]) {
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 字符数组两种写法:
char str1[] = {'i', 'P', 'h', 'o', 'n', 'e'};
char str2[] = "iPhone";
// 字符串默认使用 '\0' 作为结束标示,使用双引号的方式,自带 '\0' , 使用数组的方式,需要手动添加 '\0' 才可以成为字符串
}
#pragma mark - 第六章:函数
void func6();
void func6()
{
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 在函数调用的时候,只能调用上面的函数,不能去调用下面的函数,如果想要调用下面的函数,需要在上面进行声明
// 函数可以嵌套调用,但是函数不可以嵌套定义
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数的形参:出现在函数定义中的变量,值是从实参拷贝过来得
// 函数的实参:在函数调用的时候传递给函数的,可以通过指针的方式修改实参的值
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 普通变量作为参数的时候,修改形参的值,实参的值不会发生变化
// 当数组作为参数的时候,修改形参的值,实参的值会跟着发生变化,因为,数组作为参数时候,传递是的数组的首地址,操作的是同一块内存区域
}
#pragma mark - 第七章:结构体
void func7();
void func7()
{
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 定义类型
typedef struct {
char name[30];
int age;
float score;
} Student;
// 创建变量
Student stu = {"lidaze", 18, 100.0f};
// 访问成员变量,使用 ‘.’ 的方式访问
printf("name = %s age = %d score = %.2f\n", stu.name, stu.age, stu.score);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 结构体是可以嵌套的
// 访问的时候,使用 '.' 依次找到实例变量进行操作
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 结构体变量可以直接赋值
// 我们可以通过把数组放在结构体中,实现数组的直接运算
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 结构体内存占用
// 以最大成员变量类型所占空间为分配单位
// 按结构体成员声明顺序自上而下分配
// 注:分配空间不足以存储成员变量时,分配新的空间单位
}
#pragma mark - 第八章:指针
void func8();
void func8()
{
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 指针的算术运算
int a = 10;
int *p = &a;
p++;
p--;
// 指针的运算是移动一个单位的长度,这个长度到底是多少个字节,取决于指针的类型
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// '*' 的作用:
// 在定义指针中,‘*’ 起到告诉编译器,要声明的是一个指针
// 在指针的使用过程中,使用‘*’,此时‘*’是取值运算符,根绝内存地址,拿出这空间内得内容
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 指针与数组
int array[] = {123, 42, 52, 5, 32, 535, 35, 343};
int *p1 = array;
// 数组名代表数组的首地址,用指针指向数组的时候,直接把数组名赋给指针变量即可,不需要使用‘&’符号
// 数组名和指针的使用方式一样
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 指针与结构体
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 指针与结构体
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 详细内容见:http://blog.sina.com.cn/s/blog_9c2363ad0102uxlw.html
}
#pragma mark - 第九章:结构体指针
void func9();
void func9()
{
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
typedef struct {
char name[20];
int age;
} Student;
Student stu = {"lidaze", 18};
// 指针指向结构体变量,类型需要相同
Student *p = &stu;
// 使用指针访问结构体成员,很特殊,使用 '->'
printf("name = %s age = %d\n", p->name, p->age);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 宏定义
#define SUM(a, b) ((a) + (b))
// 使用宏定义的时候需要注意,尤其是带参数的宏,最好把每个参数和最外层都加上小括号,防止出错🙅
}
#pragma mark - 第十章:动态内存分配
void func10();
void func10()
{
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 内存共分为5个区:
// 栈区
// 堆区
// 静态区(全局区)
// 常量区
// 代码区
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 堆内存的管理需要我们手动来管理
int *p = malloc(sizeof(int)); // 分配一块空间
*p = 123;
printf("p = %d\n", *p);
free(p); // 使用完成之后需要使用
// free(p); // 不允许过渡释放,同时也不允许不释放,会造成内存泄露
// 开辟内存空间的同时,会把每一个字节清零,效率低,耗费时间,😢
int *p1 = calloc(4, sizeof(int));
// 重新分配空间
p1 = realloc(p1, sizeof(int) * 10);
free(p1);
}
#pragma mark - 第十一章:函数指针
void func11();
void func11()
{
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数指针:即是指向函数的指针
// 函数指针的提取:返回值类型 (*) (参数类型)
// void (*) (): 函数void func11()的类型
// 使用函数类型的时候太麻烦,给函数类型起个别名
typedef void (*FuncPoint) ();
// 使用指针,指向函数
FuncPoint p = func4;
// 普通调用函数
func4();
// 使用指针调用函数
p();
}
#pragma mark - 主函数
int main(int argc, const char * argv[])
{
return 0;
}