C语言期末复习

第一章

        1,数据类型——不同类型数据所占字节数(32位)

                1,int——4

                2,short——2

                3,float——4

                4,long int——4

                5,double——8

        2,常见数据类型

                3.14——这是double类型

                3.14f——这是float类型

                字符类型

                        1、'a' 单引号 表示取a的ASCII值

                        2、字符在计算机及存储的是ASCII

                        3、'a' ==97,二者完全等价

                        4,sizeof('a')是四字节

                转义字符

                        '\n' 换行         '\t' tab        ’//‘ /

                        printf("A:%d\n", '0');//48

                         printf("B:%d\n", '\0');//0

                         printf("C:%d\n", 0);//0

                        printf("D:%d\n", "0");//字符‘0’地址

                ''取的是字符的ASCII值 ""取的是字符串的首元素的地址

        3,格式控制

3 printf("##############\n");
4 //%5d 表示占5个终端位宽 右对齐
5 printf("##%5d##\n",123);
6
7 //%‐5d 表示占5个终端位宽 左对齐
8 printf("##%‐5d##\n",123);
9
10 //%05d 表示占5个终端位宽 右对齐 不足补0
11 printf("##%05d##\n",123);
12
13 //千万不能写 %‐05d
14 //printf("##%‐05d##\n",123);
15
16 //%5.2f 5表示总位宽为5 .2表示小数位保留2位
17 printf("##%5.2f##\n", 3.14159f);

C语言期末复习_第1张图片

        typedef

                为已有的类型重新 取个别名。

        1、用已有的类型 定义 一个变量

        2、用别名 替换 变量名

        3、在整个表达式的前方加上 typedef.

1 案例1:
2 int INT32
3 typedef int INT32;
4
5 案例2:给int arr[5] 取个别名 ARR
6 typedef int ARR[5];
7 ARR arr;//arr就是一个拥有5个int元素的数组

        4,数据类型转换

                自动转换,往高出转,举例

                //由于char short自身字节数 过小 很容易溢出

                //所以 只要char short参加运算 都会将自身转换成int

                强制 类型转换 只是临时的转换 当前语句有效 在后面的语句中不会更改x的值

        5,运算符

               1算数运算符

                 a /b 如果a b为整数 表示取整 如果 a b只要有一个为浮 点数 则表示除法运算结果还是浮点数

                取整 %取余 必须为整数

                2,逻辑运算符

                        逻辑非!//C语言 0为假 其他都为真 ‐1

                        逻辑与 A && B 如果A为假 系统不会执行B 这就是&&的短路特性

                        &:按位与   语法:全1为1 其他为0

                        |:按位或 语法:有1就为1 全0才为0

                        ~:按位取反 语法:0变1 1变0

                        ^:按位异或 语法:相同为0 不同为1

                        << 左移运算符: 左边丢弃 右边补0,左移n位变成2的n次方

                3,其他运算符

                逗号运算符   data1 = 3,4,5,6  //结果是3,先赋值       data2 = (3,4,5,6);结果是6

                表达式1 ? 值1:值2 语法:如果表达式1 为真 整个表达式的值为“值1” 否则 为“值2”

                a *= b; ==> a= a * b; 注意:=号 右边必须看成一个整体,a+b看成(a+b)

                4,优先级,算数,关系,逻辑,赋值

        6,循环

                continue;//结束本次循环 立即从当前位置直接 进入下一次循环

                break;//只能跳出离它最近的一层循环,或者在swich语句中

第二章数组

        1、数组的定义

                        需求:请定义一个数组 该数组 有10个元素 每个元素为int 在定义的时候:                 a、arr[] arr和[]结合是数组

                b、将确定的元素的个数放入 []中

                c、用元素的类型 定义一个普通变量

               d、从上往下整体替换。 int arr[10];

注意: 1、数组名 arr 不能和其他变量名 同名 2、数组的元素小标是从0开始:0~9 3、数组的元素 分别是:arr[0]、arr[1]~arr[9], 如果访问arr[10]数组越界。 4、数组的元素 等价于 普通变量 5、在定义数组的时候 ,[]里面的值 不能是变量(c89)。

        2,scanf,gets,fgets

        scanf和%s使用的时候 有个缺点 遇到 空格会结束输入

        //scanf("%s",buf);//不能获取带空格的字符串

         gets(buf);//获取带空格的字符串

        fgets函数 既可以获取 带空格的字符串 也可以保证 buf的不越界

1 #include

2 char *fgets(char *s, int size, FILE *stream)

3 //s表示存放字符串的空间地址

4 //size 能够提取字符串的最大长度 size‐1

5 //stream stdin 表示标准输入设备

6 返回值:就是获取到的字符串的首元素地址

第三章函数

1、函数的定义:实现函数功能、确定函数体、返回值类型、形参类型。 让函数存在

2、函数的声明:不是实现函数功能 仅仅是说明改函数有返回值类型、形参类型、函数名。

3、函数的调用:函数的执行。

        1、函数的定义

                1 //返回值类型: 函数将来返回值的类型

                2 //函数名:函数的入口地址

                3 //形参:函数外部数据 传递到 函数内部的 桥梁

               4 //函数体:具体的函数功能带

               5 返回值类型 函数名(形参类型 形参)

                6 {   函数体}

        2、函数声明:

                1 返回值类型 函数名(形参类型 形参);

        3、函数的调用

                1 //函数外部的实际数据 2 函数名(实参);

1 //函数声明:告诉编译器 该函数存在 请通过编译。
2 void my_fun();
3
4 int main(int argc,char *argv[])
5 {
6 //函数的调用:函数名+()
7 my_fun();
8 return 0;
9 }
10
11 //函数的定义
12 void my_fun()
13 {
14 printf("my fun\n");
15 return;//1、返回函数结果 2、结束函数
16 }

第四章预处理

        1,内存分区

C语言期末复习_第2张图片

                        1,全局变量

生命周期:整个 进程 都有效(程序结束的时候 全局变量 才被释放)
存储区域:全局区
注意事项
a、全局变量 不初始化 内容为 0
b、如果全局变量 要在其他源文件中使用 必须在所使用的源文件中加extern声明。
c、如果全局变量 和 局部变量 同名 在{}中优先使用局部变量
                        2,静态全局变量
作用范围:当 前源文件 有效 不能在 其他源文件中使用
1 #include < stdio . h >
2 static int data = 10 ; // 静态全局变量
3 int main ( int argc , char * argv [])
4 {
5
6 return 0 ;
7 }

                        2,静态局部变量

作用范围:离它最近的{}之间有效。
1 void test01 ()
2 {
3 {
4 static int num ; // 静态局部变量
5 }
6 // 说明 静态局部变量 只在离它最近的 {} 有效
7 printf ( "num = %d\n" , num ); //err 不识别 num
8 return ;
9 }
      
                        3,局部变量,定义在{}内,离开{}失效
第五章指针

 1,指针就是地址,每个字节都有对应的地址,指针变量本质就是个变量存放的是地址编号,任何地址编号都是四个字节,也就是sizeof(int *  char* double ***)都是四个字节

2,如何定义一切指针

        1、*修饰 指针变量名                                                                //   *p

        2、保存啥类型变量的地址 就用该类型定义一个普通变量。    //    int num

        3、从上 往下 整体 替换                                                            //   int *p

3,*p什么意思?

*p表示取p保存的地址编号对应的空间内容。*p等价于num

4,指针变量的类型

        1,指针变量自身类型(p是什么类型)        只将指针变量涂黑,剩下啥类型,指针变量自身就是啥类型。        比如 p自身的类型是int *

        推广,int num,num的类型是?把num涂黑

        2,指针变量所指向的类型?        将指针变量和最近的一个*一起涂黑剩下啥类型就指向啥类型         p指向的类型为int类型 == p保存int类型变量的地址

              即指向XXXX类型 == 保存XXX类型变量的地址

指针变量取值宽度,指针变量取值跨度,都取决于指针变量指向的类型

5  指针变量的初始化

//如果 局部 指针变量 不初始化 保存的是随机的地址编号(千万别取值) int *p;

//不想让指针变量指向任何地方 应该初始化为NULL(千万别取值)  //#define NULL ((void *)0)

 int *p1 = NULL;

//将指针变量初始化为合法的地址(可以取值)        int *p2=&a;

//千万别看成 *p2 = & num;        是先 int * p2; p2 = &a  *修饰p2为指针变量        

6,&&与**的区别

//如果对一个变量取地址 整个表达式的类型 就是变量的类型+*.

//p的类型是 int *类型 

//*p的类型是 int 类型

//如果对指针变量取* 整个表达式的类型是 指针变量的类型‐*.

//高级总结:如果&和*同时存在 可以相互抵消(从右‐‐>左)。(重要)

7,数组与指针

        1, []与*()关系  //在使用中 本质:[] 是*( ) 缩写

         //缩写规则:+左边的值 放在[]左边边 +右边的值 放在[]里面

        arr[i]=*(arr+i)

        2,arr代表的是 第0个元素的地址(&arr[0])

        //&arr[0] == &*(arr+0) == arr+0 == arr 

        //所以:数组名arr代表第0个元素的地址,&arr是数组的首地址

        arr+1代表首元素地址+1,跳过了一个元素(4B)

        &arr+1代表是数组的首地址+1,跳过整个数组(4*5B)

        3,数组名arr是一个符号常量,不能被赋值(不能放在等号左边)

8,指针数组:本质就是数组,只是数组的每个元素都是指针

        1,定义,就是数组的定义,int arr[5]

                                                       *arr

                                                        int *arr[5] 

        int *arr[3]={&num1,&num2,&num3}        这个数组有三个元素,每个元素是什么类型?

        把arr[3]涂黑,剩下int *,每个元素是int *

        2, 指针数组保存字符串

        char * arr[3]={"hehe","haha","heihei"};

        数组每个元素保存的是字符串首元素的地址,即arr[0]保存的是‘h’的地址

        而字符串储存在文字常量区,是只读的

        那如何打印字符串?

        printf("%s",arr[1])

        如何打印arr[1]中的字符a,printf("%c", *(arr[1]+1)  )首元素的地址加一,再解引用

void test12()
{
	int arr[5]={10,20,30,40,50};
	int *p = arr;

	printf("%d\n", *p++);//10
    ++运算级搞,但是因为是后自增,所以先算*p,再把p++,此时,*p=20

	printf("%d\n", (*p)++);//20
先算*p就是20,然后再20++,(*p)++等价于(*p)=(*p)+1,此时*p等于21

	printf("%d\n", *(p++));//21
}

9,数组指针          本质就是指针,保存的是数组的首地址,p=&arr

        1,定义,就是定义一个指针,*修饰变量名*p        定义一个变量int arr [5]                                    替换int(*p)arr[5]

        *修饰p为指针变量,指针变量保存什么类型的地址?把*p涂黑,保存的是数组的地址

         是数组的地址(&arr)不是数组首元素的地址(&arr[0])

        该数组有五个元素,每个元素是什么类型?

        2,p=&arr,p+1跳过4*5个字节

        如何利用p取出arr[3]  40?

        如果p是=&arr[0]也就是p=arr,只要*(p+3),但是p=&arr故同时解引用,*p=arr

        故arr[3] = *(*p+3)

        睁大眼睛,*p看成*(p+0)=p[0],   见到*()想到变成p[]

        *(p[0]+3)= p[0]p[3]        也就是说一维数组看成只有一行的二维数组

10,二维数组        int arr[3][4];

        1,二维数组名代表行地址,加一跳过一行        arr+1就是第1行地址

        2,对行地址取*就代表当前行第零列的列地址,*(arr+1)就是第一行第零列地址,再对他加一加二就可以取这一行其他元素的地址

        3 ,组合技,如何取出第一行第二列的元素?

        *(arr+1)第一行第零列元素地址,*(arr+1)+2,在对他解引用,*(*(arr+1)+2)

        化简,==  *(arr[1]+2)==arr[1][2]

        4,案例, int arr[3][4]

        *arr+2   第零行第二列的列地址

        arr[1]        等于*(arr+1)第一行第零列的列地址

        &arr[0]+2        化简==&*(arr+0)+2==arr+2第二行的行地址

        **arr        化简==*(*(arr+0)+0)==arr[0][0]

11,数组指针与二维数组的关系

        1,定义一个指针变量,保存二维数组的行地址   int arr[3][4]

        数组指针          int (*p)[4]        p=arr        p完全等价与arr

        2,二维数组的行数        int row = sizeof (arr)/sizeof(arr[0])

        二维数组的列数        int col=sizeof(arr[0]/sizeof(arr[0][0]))

12,指针变量作为函数参数

        1,如果想在函数内部修改外部变量的值,就要将外部变量的地址传递给函数(以指针变量作为函数的参数)

13,一维数组名做函数参数

        1,如果函数内部想操作外部数组元素,请将外部数组的数组名传递给参数

        2,一维数组作为函数的形参,会被优化为一级指针

        int arr[5]        int arr[]----->int *p

        int arr[3][4]----->int(*p)[4]

        int arr[3][4][5]------->>int(*p)[4][5]

14,函数指针

        1,定义,  *p   int func (int a , int b)替换得到,int (*p)(int a,int b)

        2,函数名代表函数入口地址,就是个地址  p=func

        3,对函数指针取*****无意义

14,malloc和free函数

1 #include
2 void *malloc(unsigned int num_size);
3 形参:num_size需要申请空间大小的字节数。
4 返回值:
5 成功:返回空间的起始地址
6 失败:NULL
7 特点:
 1、对于malloc的返回值 一般要强制类型转换
 2、malloc申请的空间 内容不确定 一般使用memset进行清空
 3、多次调用malloc 第1次malloc 和 第2次malloc的地址不一定连续
案例

void test02()
2 {
3 int *addr = NULL;
4
5 addr = (int *)malloc(sizeof(int));
6 if(addr == NULL)//申请失败了
7 {
8 printf("malloc err\n");
9 return;
10 }
11
12 printf("*addr=%d\n", *addr);//不确定的值
13
14 //对堆区空间 清0
15 memset(addr, 0, sizeof(int));
16 printf("*addr=%d\n", *addr);//0
17
18 //对addr的空间 就行写 或 读
19 *addr = 1000;//写
20
21 printf("*addr=%d\n", *addr);//1000 读
22
23
24 //释放堆区空间 空间使用权限的回收 是否对空间内容清0 这是不确定的
25 free(addr);
26 }
27 int main(int argc,char *argv[])
28 {
29 test02();
30 return 0;
31 }

你可能感兴趣的:(c语言,开发语言)