C语言大总结

C语言大总结

一、基础:

1、进制、位权、1字节等于8位(位是计算机的最小储存单位,字节是计算机最小存储单元)、十进制转换其他进制:连除倒取余,其他进制转换十进制:按权求和
2、单行注释:// 多行注释: /**/ (内容写在量型号之间)
3、数据类型:整形类型、浮点类型、字符类型。
整型类型:长整形(long 4/8)、整形(int 4)、短整型(short 2)
浮点类型:单精度(float 4)、双精度(double 8)
字符类型:字符类型(char 1)
4、常量:程序运行期间不能被改变的量。
常量 类型:整型常量、浮点型常量、字符型常量
变量:实际上是储存区域,也可以做表达式,是程序运 行期间可以被改变的量。
变量定义:由类型符号、变量名、初始值三部分组成(如: int a = 5;)
变量命名规则:由数字、字母、下划线组成的,但不能 以数字开头,不能与关键字重复,不能重复使用变量名(同一作用域),见名知意。
5、赋值运算符:= 把右边的值赋给左边 优先级别最低
算数运算符:+, -, *, / 整型两边相除取整,除数不能为0,% 两边均为正数 ,++ 自增运算符、- - 自减运算符:(它俩在前,先执行,它俩在后,后执行。
6、复合运算符:+= (a += b; 相当于a = a + b); -=; *=; /=; %=;(语法含义同上)
7、表达式:由常量、变量与运算符组合而成(注:表达式会有返回值)
8、输出函数:printf(); 输入函数 scanf()(注:以回车确定输入结束,只有大回车键才会结束;不要再格式串后面加’\n’字符,否则会抵消人工输入的回车)。
转化符:%c->char; %d->int; %sd->short; %ld->long;%f->float、double。
9、转换格式控制:最少占4位:
printf(“%04d”,12); //不足补0
printf(“%4.2f”,1.2345); //保留小数点后两位
printf(“%-4d”,12); //左对齐
\n回车符; \打印\; %%打印%;

二、运算符

1、BOOL类型:只有YES(1)和NO(0)两个值;
bool类型:由ture(非0数字)和flase(0)两种值;
BOOL和bool区别:1)、在C中只有小布尔没有大布尔; 2)、在C和OC中小布尔中非零为真,零为假;3)、在OC中大布尔中1为真,0为假,其它数字原样输出,不做判断条件
2、关系运算符:用于比较运算,结果值有真假两种,结果值由BOOL类型储存
> < >= <= == !=
3、逻辑运算符:由逻辑运算符组成,结果也是非真即假
&&(逻辑与):一假即假(有一边为假则结果为假)
||(逻辑或) :一真即真(有一边为真则结果为真)
!(逻辑非) :对表达式结果取反
4、条件运算符:条件表达式?表达式1:表达式2
如果条件为真,则执行表达式1。 如果条件为假,则执行表达式2。
5、枚举类型:属于构造类型,是一组由符号的整型常量,一一罗列所有状态,罗列所有结果。 enum枚举名{枚举值表}
目的和作用:提高程序可读性;将人能看懂的标示符与计算机能识别的数字建立对应关系

三、程序的三种结构:

1、顺序结构:按照语句顺序执行

2、分支结构:判断条件在两个语句序列中选择,一旦进行判断必须选择其中一个。

if语句:形式一:if (条件表达式) {语句;}
形式二:if (条件表达式) {语句1;} else{语句2;}
形式三:if (条件表达式1) {语句1;} else if条件表达式2){语句2;} else{语句3;}
switch语句:多分支语句,通过判断整形表达式的值,来判断执行那个语句。常与case配合使用。
break:跳出本层循环,如果外层还有循环的话,则执行外层循环,如果外层没有循环,则执行循环后面的代码。(常与if、switch连用)
continue:跳出本次循环,跳出本次循环,遇到continue后,不管continue后面有无代码,均不执行,提前结束当前循环,开启下一次循环。(常与if连用)
arc4random():返回随机数的函数。 如果要一个随机数在【a, b】范围内的整数。公式为:arc4random() % (b - a +1) + a;

3、循环语句:在满足一个条件的情况下反复执行一个语 句序列。

while语句:while(条件表达式){语句;}条件表达式为真执行循环体,一旦为假立即停止执行。
do…while…语句:do{语句;} while (条件表达式),先执行循环体,再判断循环条件直到不满足,才结束循环。
for语句:for(循环变量初始化;循环条件;循环增量){语句;}循环条件为真才执行循环体。

四、一维数组

一维数组:属于构造结构,是由相同类型的成员组成的一组数据。
数组名:存储不同数据类型的数组有各种对应的名称(名称可以随意起),但 要见名知意。
元素:数组由多个成员组合而成,每个成员被称为“数组的元素”

1、定义一个数组

int array[3] = {1, 2, 3};
int:声明数组类型 array:数组名 [5]:数组长度(注:定义数组时,可以省略元素个数,因为编译器会自动推断出元素个数,但是“[]”坚决不能省略。) { } :给数组赋值,元素之间用逗号分隔开(注:1)定义数组时,可以不给每一个元素赋值,没有赋值的元素系统会默认为0。2)定义数组时,给定了数组长度,首元素为0,其他元素不赋值,则默认为0,这样五个元素均为0。3)大括号中最好赋上初始值,因为没有赋值是系统会根据Xcode编译环境来赋值,有时可能有,有时可能无,这样就会出现定义不明,所以建议赋上值。)

2、数组的内存占用

1)使用sizeof()函数求数组占字节数
printf("array[3]数组所占字节数%ld", sizeof(array));
结果:12 因为每个int类型占4个字节,有3个元素,所以共12个字节 。
2)利用sizeof()函数求数组元素个数
先求出数组所占字节数,再求出其中某个元素所占字节数,再相除就得出数组元素个数。
int array[5] = {4, 6, 7, 2, 8};
int a = (sizeof(array) / sizeof(array[1]));
printf("a = %d\n", a); 结果为:a = 5

3、数组元素的访问方式:数组名+下标

1)int array[6] = {12, 21, 32, 23, 25};
访问array中的32这个元素: 数组名:array,下标:从零开始计数,32在第3个位置上,所以32的下标是2。
int temp = array[2];
printf("temp = %d, array[2] = %d\n", temp, array[2]); 结果:32,32
(注:可以直接访问,打印出来,也可以把值赋给另一个相同类型的变量再打印出来)
2)数组下标越界:数组下标超过了数组长度,访问了不属于数组的内存空间。在C中是没有“数组下标越界保护”机制,所以在写代码时,要避免下标越界。
3)修改数组元素

3.1)修改array中的第二个元素为62
int array[6] = {12, 21, 32, 23, 25};
array[1] = 62;
printf("array[1] = %d\n", array[1]);   结果:array[1] = 62
3.2)  定义一个新的数组,array1,将array的元素,原样赋给arrary1.
int array[5] = {12, 21, 32, 23};
int array1[5] = {0};
for (int i = 0; i < 5; i++) {
 array1[i] = array[i];     //  数组的下标可以是常量,也可以是变量
printf("array1[%d] = %d\n", i, array1[i]); // 数组的输出需要for循环进行遍历
}   
//  array1 = array;  数组中不能整体访问数组元素,也不能整体赋值,而要逐一的遍历数组元素,进行访问、赋值、输出。
//  定义一个具有20个元素的数组,每个元素的取值范围是【30,70】,求数组元素的和
     // 1.定义一个整型数组长度为20
    int array[20] = {0};
    //  2.开启一个for循环,使用循环给数组元素赋值
    for (int i = 0; i < 20; i++) {
        //  2.1 生成【30,70】之间的数
        int temp = arc4random() % (70 - 30 + 1) + 30;
        //2.2 将生成的随机数赋值给对应的元素
        array[i] = temp;
        printf("array[%d] = %d\n", i, array[i]);
    }
    //  3.求数组元素的和
    //   3.1定义一个保存和的变量
    int sum = 0;
    //3.2 使用for循环遍历数组元素,同时将元素累加起来
    for (int i = 0; i < 20; i++) {
        // 3.2.1 获取当前数组元素并将获取到的元素加起来
        sum = sum + array[i];
        
    }
    printf("元素总和为%d\n", sum);
//   定义三个数组,将随机产生的数放入其中两个数组中,将这两个数组的值加起来放入第三个数组中
// 1、 定义三个数组,并初始化。
    int array1[10] = {0};
    int array2[10] = {0};
    int array3[10] = {0};
    // 2、 使用一个for循环,给第一个数组和第二个数组赋值,将两个数组个元素加起来,交给第三个元素。
    for (int i = 0; i < 10; i++) {
     // 2.1、 分别把生成的随机数赋给两个数组
        array1[i] = arc4random() % (40 - 20 + 1) + 20;
        array2[i] = arc4random() % (40 - 20 + 1) + 20;
     // 2.2、两数组进行相加
        array3[i] = array1[i] + array2[i];
    // 3、 打印验证结果是否正确
        printf("array1[%d] = %d, array2[%d] = %d, array3[%d] = %d\n", i, array1[i], i,array2[i], i,array3[i]);
   } 

4、冒泡排序

int array[5] = {12, 45, 23, 42, 56};
    //趟数 = 元素个数 - 1;每趟比较的次数 = 元素个数 - 当前的趟数
    //两层for循环,外层丛植比较趟数、内层控制比较次数
        //趟数
        for (int j = 0; j < 5 - 1; j++) {
            //次数
            for (int k = 0; k < 5 - (j+ 1); k++) {
                if (array[k] > array[k + 1]){  //因为每趟比较都要从下标为0开始,j在每次从外层循环进入内层时,都要被初始化为0。因为每次比较,下标都要加一,j在每次内层循环时,也会加一,所以,在这里是用j做下标是没有问题的。
                    //满足交换条件,开始交换位置。
                    //1.定义一个临时变量
                    int temp = array[k];   6
                    array[k] = array[k + 1];
                    array[k + 1] = temp;
                }
            }
        }
    for (int i = 0; i < 5; i++) {
        printf("%d ", array[i]);
    }

5、字符数组

字符数组:保存字符的数组就是字符数组。有’\0’结束标识的字符数组也称为字符串。
定义一个字符数组:声明类型、数组名、数组长度、赋初值
char char_Array[5] = {'h', 'e', 'l', 'l', ‘o’};
//每个字符占一个字节,数组长度是5,所以数组占5*1个字节的内存。
char char_Array[5] = {'h', 'e', 'l', 'l', 'o', '\0'};和char char_Array[5] =“hello”;
是同一个意思都便是定义字符串hello。
字符串和字符数组的区别:
如果字符数组最后一个字符末尾没有‘\0’,则是一个字符数组
如果字符数组最后一个字符末尾有‘\0’,则是这个字符数组就是字符串。
字符串操作函数
strlen():返回字符串的有效字符个数
strcpy():字符串拷贝函数:把第二个参数的值拷贝给第一个参数
strcat() 字符串拼接:把第二个参数的值,拼接到第一个参数的后面
strcmp() 字符串比较:第一个参数大于第二个参数返回一个正整数,第一个参数小于第二个参数,返回一个负整数,两个参数相等,返回零。

五、函数

1、函数:完成某一功能的代码段。

函数名:给这段代码取一个名字,以后就可以通过这个名字来代替这段代码,遵守变量名的命名法则。
函数参数: 有的函数在完成某一任务时需要的材料,我们把在完成任务所需的材料叫函数的参数。 在被调函数中,参数叫“形参”,在主调函数中,参数叫“实参”。
函数参数传递:将实参的值拷贝一份到形参变量的空间中,在被调用函数中操作的参数是新开辟的内存的数值,和实参没有关系。
参数列表:如果没有参数,可以用void修饰,也可以什么都不写,但是小括号不能省略。
函数的返回值:有的函数在完成任务之后,需要把任务结果返回给主调函数,就可以通过return语句来将值返回。注意:return只能返回一个值,同时不能返回数组。
return:return标志着函数的结束,如果return后边有数值,则将这个数值交给主调函数。当return只负责结束函数执行时,可以省略return。return后⾯的语句不再执行。
函数定义:一般定义在main函数前,函数会遭遇嵌套定义。
返回值类型 函数名 (参数列表) {函数实现……return 返回值;}
函数的调用:必须要先定义出来这个函数,定义之后才能调用
函数调用方式:函数名+参数列表
函数类型:无返无参,无返有参,有返无参,有返有参
返回值类型:如果无返回值,必须要使用void修饰符

2、.h和.m文件

1)如果使用多个文件来管理定义函数时,函数的声明要放在.h文件中,函数定义在.m文件中。
2)由于函数的声明和定义在其他文件中,所以想使用该函数,必须先引入声明部分,也就是.h文件

#import"文件名.h"  把这个放在   主函数和系统头文件之间

3) 如果函数定义在主调函数(main)函数之前,函数的声明可以省略,因为在编译时,编译到主调函数时,已经知道该函数被调函数的意义,所以不会出现异常。如果函数定义在主调函数(main)函数之后,务必要在main函数之前对函数进行声明。
4)声明的意义在于:告诉系统,后面将会出现一个该类型的函数。一个完整的自定义函数,应该包括:函数声明、函数定义、函数调用,共三部分。
5)函数声明的方法:将函数的“返回值类型+函数名+形参列表+;”写在导入头文件语句下面,就是一个函数声明。

3、函数的嵌套调用

1)函数可以嵌套调用:在一个函数中,调用另一个函数完成某项功能,这就是函数的嵌套调用。函数可以嵌套调用,但是函数不可以嵌套定义。
2)函数不可以嵌套定义:在定义一个函数时,又定义另一个函数,就叫函数的嵌套定义,这种行为是不允许的。

4、函数的递归调用

函数递归时一定要有出口,否则会造成程序递归环路(死递归),那么程序一定会崩溃。递归调用:自己调用自己完成某项功能。

5、变量的作用域

//  局部变量:只在当前作用域中起效
//  全局变量:不属于任何一个作用域的变量就是全局变量,全局变量可以在当前文件中任何一个地方被访问到(从创建的位置开始,一直到文件结束)
//  如何确定作用域?使用{}来确定作用域,一对大括号,就确定了一个作用域。

六、结构体

1、什么是结构体?

 1、)结构体是一种构造类型,由其他基本数据类型组合而成一种新类型。与数组的区别是:构成结构体的基本数据类型可以不相同,数组必须是相同类型的数据构成。
 2、)结构体必须先声明,声明结构体由哪些数据类型构成的,相当于基本数据类型的“int/char/double”之类的类型说明。
 3、)声明完成后,就在文件中创造出了这种新的类型,就可以使用这种新的类型定义变量来保存数据了。

2、结构体类型的声明

struct+结构体名+{成员标量}+;  结构体声明在.h文件或主函数与系统头文件之间。
eg:struct student {
    char name[20];
    int age;
    char gender;
};

3、结构体定义

1)struct关键字+结构体名,共同组成了变量的类型修饰符。
struct+结构体名+结构体变量名 = {值1,值2};
eg:struct student stu1 = {"zhangSan", 23, 'm'};
2)结构体成员变量的访问
方式:使用结构体变量名+“.”+”成员变量”的方式访问
eg:访问姓名:stu1.name 访问年龄:stu1.age 访问性别:stu1.gender
3)结构体成员变量的修改
先访问到对应的成员变量,然后再修改值
修改成员年龄:stu1.age = 22;
修改成员性别:stu1.gender = ‘f’;(输出打印时用%c)
修改成员姓名:stu1.name = "shuKui"; (这是错误的形式)
因为字符串在C中使用时,字符数组类型保存的数组不能整体赋值,所以使用普通的修改成员变量方法在这里无效,需要使用字符串拷贝函数,达到修改的目的。
strcpy(stu1.name, “shuKui"); (使用strcpy()函数进行字符串的复制替换)

4、结构体数组

保存结构体变量的数组,就是结构体数组。结构体数组和基本数据类型的数组一样,只能保存相同的数据元素(结构体变量类型必须相同)

1)声明一个father类型的结构体数组
typedef struct father {
    char name[20];
    int age;
}father;
2)定义一个father类型的结构体数组
father father[4] = {
{"zhangsan", 12},
{"laowang", 55},
{"xiaotian", 66},
{"xiaoyan", 22}
};
3)访问成员变量的方式:数组变量名 + 下标 + ‘.’ + 成员变量名
访问姓名:father[0].name
访问年龄:father[2].age

七、指针

1、指针:指针就是内存单元编号的另一种称呼。每个内存单元都有一个编号,这个编号就是内存单元的地址,也被称作指针。

指针变量:用来保存“内存单元”地址的变量,就是指针变量。

2、定义一个指针变量

1)int p = NULL; int a = 12;
// int * : 类型声明符,表示变量p是一个整型指针变量。
// int:告诉系统取值时,应该从当前位置取多少字节数据。int表示连续取4个字节。它与指针变量所占字节无关,指针变量所占字节数只与操作系统有关,64位环境下占8字节,32位环境下占4字节。
// 不能使用指针计算数组元素的个数,因为指针所占的内存的字节数至于操作系统的位数有关
// p:变量名,一般我们将指针类型的变量取名叫p。
// NULL:C语言中,使用NULL代替“空”的意思,将NULL赋给指针,则指针此时保存的是内存起始地址,指针指向内存的起始位置。
printf("%p\n", p); // 打印结果0x0,表示内存的起始位置。
// 使用%p作为占位符,来打印指针变量所保存的地址。
2) &:取地址符号,将后边变量的地址取出来,交给指针保存。
将整型变量a的地址,交给整型指针变量p保存。
p = &a; printf("%p\n", p);
3)
:取值运算符,将指针所指的内存地址中保存的数据取出来。
注意:在不同的位置的含义不同,出现在指针定义的位置,表示证明后边的变量名是一个指针。如果前边没有类型修饰符,则表示指针所指向的地址的数值。
int b = *p; printf("%d\n", b);
4)用指针修改变量 a 的值
*p = 23; printf("%d\n", a);
5)指针重指向:就是指针把它里面保存的地址进行个更换。
p = &c; 指针发生了重指向,有原来的指向a改变为指向b。

3、指针的算术运算

p++; // 指针变量进行加法操作,指针所保存的地址将会加若干个单位的字节,每个单位占用的字节数取决于指针的类型。指针从低地址向高地址移动。
p- -; // 指针变量进行减法操作,指针所保存的地址将会减若干个单位的字节,每个单位占用的字节数取决于指针的类型。指针从高地址向低地址移动。
// 普通的加减运算:如果没有小括号干预优先级,则先取值,再将值进行加减操作
// 自增、自减运算:先处理自增、增减,处理完成后,再进行取值操作。

4、指针与数组

1)数组名就是数组的首元素地址,我们可以定义一个指针变量,来存储数组的首地址,这样指针变量指向的就是这个数组。
// 定义一个指针,将指针指向数组array的首地址
int *p = array; // 数组名本身就是地址,所以不需要取地址符&
// 访问数组元素:数组名+下标\指针+下标
printf("array[1] = %d\n", array[1]);
printf("p[1] = %d\n", p[1]);
// 打印指针指向的地址和数组首元素的地址以及数组名指向的地址
printf("%p\n", p);
printf("%p\n", &array[0]);
printf("%p\n", array);
2)数组名和指针的区别:
2.1)指针指向数组的首地址后,可以向数组名一样访问数组元素(数组名/指针);
2.2) 指针变量的地址可以被修改,但是数组名是一个常量,它所保存的地址不能被修改(数组名不能重指向,但是指针可以重指向)
3)// 使用指针的方式来访问数组元素
int temp = *p; int temp1 = *(p + 1); int temp2 = *(array + 1);
// 此时指针P的指向并没有发生改变,而是产生了一个"新指针(p + 1)"指向了第二个元素。
// 通过修改指针P的指向,来访问数组元素;
int temp3 = * (++p); printf("temp3 = %d\n", temp3);
int temp4 = * (++array); // 因为数组名是常量,所以不能通过修改数组名的地址修改数组元素。(这种表示是错误的)

5、使用指针遍历数组

int array[5] = {23, 12, 34, 23, 45};
int *p = array;

6、指针与字符串

1)// 定义一个字符数组用来保存字符串"hello"
char string[] = “hello"; // hello 是存储在常量区的,string将hello拷贝一份放到栈区进行使用。
// 定义一个char类型指针指向string
char *p = string; //这种情况是指针指向有string开辟的栈区的hello的首地址
// 使用指针下标为0的元素改为’a’

  • p = ‘a’;
    // 使用指针操作字符串:输出字符串,使用%s做占位符,参数用指针名,或数组名均可。
    printf("%s\n", p);
    // 使用指针便利字符串
    for (int i = 0; i < strlen(string); i++) {
    printf("%c\n", *(p+i));
    }
    2)// 指针p此时指向常量区,所以不能修改常量字符串的值。常量字符串,只能访问不能修改。
    // char *p1 = “hfjhsdjfh"; // 这种情况是指针指向常量区
    // printf("%s\n", p1);
    // 总结:指针指向栈区的字符串,可以访问进行修改,但是当指针指向常量区时,只能访问不能修改。

7、指针数组

1)char *str[3] = {"ios", "ipad", “imac”};这是指针数组
// str[0],相等于第一个指针,指向ios首地址。
// str[1],相当于第二个字符指针,指向常量区的ipad字符串的首地址。
// str[2],相当于第三个字符指针,指向常量区的imac字符串的首地址。
char srt[3][5] = {"ios", "ipad", “imac"};这是二位数组(两个表达意思一致)
// char * 类型的数组里存的并不是三个字符串,而是三个字符串的首地址。如果用数组存储三个字符串,需要使用二维数组。
// 指针数组中保存的元素都是指针。
// str本质是一位数组,str数组中存储的时char类型的指针。
2)访问
printf("%s\n", str[1]); // 这就访问了str[3]中的第二个元素(字符串)
3)修改:修改指针数组的元素。在这里,就是修改指向。
str1[2] = "Happy Birthday";
printf("%s\n", str1[2]);
4)使用指针打印:1、字符串的地址2、一个完整的字符串3、字符串中,下标为3的字符
// char *p2 = "i love";
// printf("%p\n", p2);
// printf("%s\n", p2);
// printf("%c\n", *(p2+3));
// 打印ipad中的第二个字符。
char *str2[3] = {"ios", "ipad", “imac"}; printf("%c\n", *(str2[1]+1));

8、指针作为函数的参数

// 对两个整型数值进行交换

//  1、函数exchangeNum定义
void exchangeNum(int *a, int *b){   传入的参数必须是指针(地址),这里坚决不能传入数组名,虽然数组名是地址,但是数组是常量怒能被改变所以不能传。(用指针传参本质是把要交换的变量的地址传过去)
    int temp = *a;
    *a = *b;
    *b = temp;
}
int main(int argc, const char * argv[]) {
    int x = 23, y = 88;
    int *p1 = &x;
    int *p2= &y;
//   调用exchangeNum函数
    exchangeNum(p1, p2);
    printf("x= %d, y = %d\n", x, y);
    return 0;
}

9、结构体指针

指向结构体变量的指针就是结构体指针。结构体指针的类型必须和结构体变量的类型一致。

//  声明一个Student类型的结构体变量
typedef struct student {
    char name[20];
    int age;
    float score;
    char gender;
}Stu; 
//  定义一个Student类型的结构体变量,并赋值
Stu stu1 = {"xiaoZeMaLiYa", 22, 98.15, ‘f'};
//    使用结构体变量名+.+成员变量名的方式访问
    printf("%s\n", stu1.name);
    printf("%c\n", stu1.gender);
//  定义一个指针,来指向这个结构体变量
    Stu *p = &stu1;    //   结构体变量名只是一个名称所以需要取地址符
//  使用指针访问结构体变量的成员变量
//  方法一:先取出结构体变量的值,再通过“.”找到它的成员变量
    printf("%s\n", (*p).name);  //  由于.运算的优先级高于*,所以需要用小括号干预他们的运算顺序。
    printf("%d\n", (*p).age);
//  方法二:使用指针名+ -> 访问结构体的成员变量。
    printf ("%s\n", p->name);
    printf("%d\n", p->age);
//  访问name成员变量的首个字符及第六个字符
    printf("%c\n", *(p->name));
    printf("%c\n", *(p->name+5));

10、指针与结构体

结构体数组的数组名就是一个结构体指针,只不过数组名是一个常量,不能修改数组名保存的地址。

typedef struct teacher{
    int num;
    char name[20];
    char gender;
    float score;
}Teacher;
    Teacher *stuu = student;
   //   使用数组名+下标的方式,访问第一个元素的name成员变量
   printf ("%s\n", student[0].name);
   //    使用指针取值的方式来访问第二个元素的num成员变量(不常用)
   printf("%d\n", (*(stuu+1)).num);
   //   使用指针和 -> 的方式访问第三和元素的gender成员变量
   printf("%c\n", (stuu+3)->gender);

八、宏

###1、普通宏
#define kMac 33  //  宏定义:在程序,只要遇到kMac,在编译之前会自动替换为后面的数。  宏不是变量
命名规则: 纯大写或 k + 驼峰法
2、带参宏
#define SUM(A,B) ((A) * (B))   //  带参宏只是将参数原样替换所以一般情况下,要在表示参数的字符上,添加小括号,防止出现运算符优先级别的问题。   
//  带参宏和函数区别:  带参宏会增加预编译的时间,但是不会加大CPU的运算速度;函数虽然在预编译阶段非常快但是占用的CPU内存会加大,增大硬件损耗。
3、条件编译指令
作用:按条件不同,编译不同的代码
  1)第一种形式:如果宏定义了标示符,则编译第一段代码,否则编译第二段代码
#ifdef 标识符
   代码段1
#else
   代码段2
#endif
 2)第二种形式:如果没有定义表示符,则编译代码段1,否则编译代码段2
#ifndef 标识符
   代码段1
#else
   代码段2
#endif
3)第三种形式:如果 常量表达式结果非0  编译器编译代码1,否则编译代码段2
#if 常量表达式
   代码段1 
#else
   代码段2
#endif

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容