某坑爹公司的笔记_Day06-Day11

这么久没更新blog了,放出一个连续的~


【Day 06】

循环

.循环

a.循环就是重复执行循环体(语句、语句块)的一种语句,在C语言中,每一个循环都有一个控制表达式(循环终止的条件),每次循环的时候,都要向控制表达式求值,如果表达式的值为真(1),那么继续循环,如果值为假,终止循环。

b.C语言中使用循环语句来反复执行特定的代码段, C语言中循环有三种表现方式:for/while/do while

c.for循环

1).语法规则

for(表达式1;表达式2;表达式3){

循环体;(可以是一条或多条语句)

}

表达式1:用来标识每一次循环,初始值

表达式2:用来判断循环是否执行的控制语句

表达式3:每次循环之间的规律,步长

d.循环的执行顺序

1)第一次执行循环语句的时候

执行表达式1->表达式2(真)->循环体

执行表达式1->表达式2(假)->终止循环

2)第二次执行循环语句的时候

执行表达式3->表达式2(真)->循环体

执行表达式3->表达式2(假)->终止循环

3)第n次执行循环语句的时候

执行表达式3->表达式2(真)->循环体

执行表达式3->表达式2(假)->终止循环

e.for(;;) 编译不会报错,循环次数是不确定的,死循环,永远的执行下去。ctrl+c强制终止循环。

f.break关键字,不但可以终止switch语句,也可以终止for循环语句。

g.continue关键字,可以终止当次循环,继续下一次循环。


二、while

while循环与for循环完全互通,除了语法格式稍有区别,其它原理、工作方式都是一样的。

a.语法格式

表达式1;                             

while(表达式2){

循环体;

表达式3;

}

b.执行顺序

1)第一次执行循环的时候

表达式1->表达式2(真)->循环体->表达式3

表达式1->表达式2(假)->终止循环

2)第二次执行循环的时候

表达式2(真)->循环体->表达式3

表达式2(假)->终止循环

3)第N次执行循环的时候

表达式2(真)->循环体->表达式3

表达式2(假)->终止循环

三、do … while

先执行循环体,再进行判断,do...while与for、while最大的不同,就算条件不成立,至少也会执行一次。

1.语法格式

表达式1;

do{

循环体;

表达式3

}while(表达式2);

2.执行顺序

a.第一次执行循环

表达式1->循环体->表达式3->表达式2(真)->继续

表达式1->循环体->表达式3->表达式2(假)->终止

b.第二次执行循环

循环体->表达式3->表达式2(真)->继续

循环体->表达式3->表达式2(假)->终止


四、三个循环的对比

1.可以控制循环的范围 for循环

2.关注循环规则 while循环

3.第一次不需要进行判断的时候 do…while

六、空语句

1.空语句常用来编写空循环体的循环

2.C语言程序习惯性的把空语句单独放一行 for(;;) ;//空语句

如果循环体只有一行,可以省略{}。


五、循环体内常用的三个关键字

break/continue/goto(强烈不建议使用)

eg:

goto escape;

escape:

printf("程序结束了\n");


————————————

【day 07】

C语言 数组

一、数组

1.概述

数组是用来存储多条相同数据类型的数据结构。(容器)

2.关键点

a.多条

b.类型相同

c.数组是数据的容器,而非数据本身

d.数组中的每一个数据,叫元素,数组由多个元素(数据)组成。

e.数据下标(索引)来区分数据中的元素

f.元素从数组的位置0开始

g.元素可以使用数组变量名[下标]来得到具体的元素

h.数组中元素的个数叫数组的长度 

i.数组所占空间=元素的类型*数组的长度

j.数组是一段连续的内存区域 指针

k.数组变量指向的区域,是数组在内存中的首地址

3.语法格式

元素的类型 数组名[长度];

int array[3];

4.初始化

a.赋使用的值

 int array2[3]={3,4,5};//依次给数组元素赋值

 int array4[3]={1,2};//如果赋值的个数少于数组 的长度,会自动用0来填充后面的值

b.赋零值

  int array[3];//未初始化 可能存在垃圾时

  int array3[3]={0};//数组中每个元素是0

5.赋值

a.数组前有类型 数字就是长度 

int array4[3];

b.数组前无类型 数字就是下标        array4[2]=10;

c.下标<长度 否则越界 

d.array4[3]=10;

6.取出数组元素的值             

printf("array4[2]:%d\n",array4[2]);

7.查看数组中的每一个元素,遍历

       遍历数组中的元素内容

    for (int i = 0; i<3; i++) {

      printf("array4[%d]:%d\n",

               i,array4[i]);

    }

8.可变数组

  在声明数组前,可以修改数组的长度,一但数组声明,其长度不可变。

  在数组长度不确定的时候,可使用可变数组。

9.数组的长度 

  数组长度=数组所占内存空间/元素所占内存空间

int size = sizeof(array)/sizeof(array[0]);

当数组过多,只要知道数组名,使用sizeof计算出数组的长度。


C语言 函数

1.概念

a.函数就是一系列语句的组合,函数名、返回值、形参、函数体组成。

b.函数在使用步骤分为三个步骤:声明、定义、调用。


——————————

【Day 08】

C语言 函数

1.概念

a.函数就是一系列语句的组合,函数名、返回值、形参、函数体组成。

b.函数在使用步骤分为三个步骤:声明、定义、调用。

2.语法格式

返回值类型 函数名(参数){

…(函数体)(返回值);

}

3.函数声明

a.正常来讲,函数在使用前一定要声明

b.由于编译器从上到下,所以下面的代码调用上面的函数,不需要声明,但上面的代码调用下面的函数,就必须声明。

c.声明的格式,去掉函数体部分,保留 返回值类型 函数名(参数);(函数的原型)

d.如果返回值类型不是int的话,最好使用函数声明(函数原型)。

e.void f();

函数声明,可以省略参数,省略参数代表可以接受任意参数,如果不需要参数,使用void关键字。void f(void);

4.函数调用

在准备使用函数的时候,执行(函数名+参数),就调用了函数体的语句。

a.有参的函数在定义时使用的参数叫形参,当调用此函数时需要传入的参数就是实参。

b.调用函数时,需要函数的执行结果,这时就需要返回值类型标识结果的类型,函数体内部需要使用return关键字,标识具体的函数结果(返回值)。

c.如果函数有返回值,当调用函数时,通常会使用变量接收返回值。

5.函数使用时注意的问题

a.如果函数执行后,不需要结果,就定义函数的返回值类型void(空),也就不需要return关键字。

b.如果执行函数需要参照一些特定的条件,就可以使用参数,如果有多个参数,之间用分隔符","。

c.使用参数的时候,相当于实参传递值给形参。

练习:有两个数i=2,j=3 使用函数调换两个数的值。在调换函数中查看i与j的值,在main函数查看调换后的值。

d.形参是数组时,采用两个参数,第一个参数是数组的长度,第二个参数是不指定数组长度的数组(数组名称)


C语言 变量的作用域和生命周期

1.变量作用域

a.表示一个变量在代码范围内是可以使用的。

通常使用'{}'符号来表示代码范围

b.在上一级代码中定义的变量,可以在下一级代码块中使用。下一级代码块中定义的变量,不可以在上一级代码块使用。

c.下一级代码块中,如果声明了和上一级名称类型一样的变量,会优先取近的变量的值。

d.局部变量:定义在函数中的变量叫局部变量

e.全局变量:定义在函数外的变量叫全局变量

f.全局变量可以供多个函数使用,而局部变量只可以供当前函数使用。

g.当全局变量与局部变量重名,依然遵守就近原则。

h.参数也有作用域,是函数的内部。

2.变量生命周期

当变量存在时,就会开辟一块内存空间。

当变量不存时,就会消除相应的内存空间。

a.当修饰局部变量的时候加auto(默认),声明变量时,会创建内存空间,当变量超出作用域,就会消除相应的内存空间。

b.当修饰局部变量的时候加static,静态局部变量,此时变量的生命周期就会变长,长到程序结束为止,虽然静态变量的生命周期变长,但作用域依然在函数内部。

c.auto是不可以修饰全局变量

d.static是可以修饰全局变量

e.加static与不加static的全局变量区别是,参考多文件情况。

小结:

作用域:使用代码范围

生命周期:变量在内存中是否存在


二、指针

1.内存被分为字节,每个字节有唯一的地址,指针指的就是内存地址。

2.保存指针的变量,就叫指针变量。

(保存地址)

3.声明一个指针变量

int i = 0;

int* p;//声明一个指针变量 int* 指针类型

int * p; int* p; int *p;


——————————

【Day 09】

一、指针

4.每个指针变量能指向一种特定类型的对象(地址,内存区域)。

5.指针是引用数据类型,因为本身没有保存数据,只是保存了数据的地址,间接的找到内存中的数据。

6.指针的用法:

a.指针可用于参数,传递变量的地址,就相当于多个函数共享内存地址(内存空间)。

值传递:相当于两个变量,不同的内存区域

地址传递:相于同一个变量,相同的内存区域


p:指针的值 地址

*p:指针指向的值 数据(区域)

&i:取变量i的地址     &i 等价 p

i:变量名                      i   等价 *p 

b.指针也可以做为返回值,但不要返回自动变量,因为局部变量的生命周期,当函数结束,局部变量会被自动清除(释放)。解决方案:延长生命周期。

c.指针支持加整数、减整数、指针的比较和相减,但运算的单位由指针的类型决定。

int类型指针+1 = 地址+4

char类型指针+1 =地址+1

d.指针与数组

1)占用空间

数组占用空间 = 数组元素占用的空间*长度

指针占用空间 = 在64位系统下,8个字节,固定的,与指针的类型没关系。

2)赋值

数组是不可以修改其值

指针是可以多次赋值


二、字符串

1.概念:一组字符数组,以数组的首地址为开始,

以ASC的'\0'为结束符。

2.字符串与普通数组的区别:普通数组没有结束标识,而字符串是有的。

3.字符串的定义方式:

a.字面值 "Hello” 

printf("Hello");

b.使用字符数组来定义字符串

char str[10]={'H','e','l','l','o','\0'};

c.使用字符指针

char* str2 = str;

4.字符串创建方式的不同

a.声明的变量,放在内存中的栈区。

b.字面值方式创建的字符串,放在内存中的代码区,如果创建的是字符串,并且值是相同的,只会创建一个内存区域,其值是只读的,值不可以改变。

c.使用数组方式创建的字符串,放在内存中的栈区,可以创建多个相同的字符串,其值可以改变。

d.字符指针,只是指向了内存的一个区域。


一、字符串

1.输入

可以接收用户从键盘上输入的数据

a.scanf() 在输入字符的时候存在缓冲区问题

通过scanf("%*c");清除缓冲区

b.scanf() 在输入字符串的时候不存在缓冲区问题,但存在安全性问题(内存溢出)。

c.fgets()函数,解决安全性问题

语法格式:fgets(参数1,参数2,参数3);

参数1:保存数据的首位置

参数2:保存的长度(包括结束符)

参数3:获取数据的方式

注:使用fgets方式输入数据的时候,会自动的在数据的后面加上'\n'

计算数据长度的时候,原有数据内容加上结束符'\0'、加上'\n'。

解决安全性问题,主要是参数2.


fgets函数用来从文件中读入字符串。fgets函数的调用形式如下:fgetsstrnfp);此处,fp文件指针str是存放在字符串的起始地址;n是一个int类型变量。函数的功能是从fp所指文件中读入n-1个字符放入str为起始地址的空间内;如果在未读满n-1个字符之时,已读到一个换行符或一个EOF(文件结束标志),则结束本次读操作,读入的字符串中最后包含读到的换行符。因此,确切地说,调用fgets函数时,最多只能读入n-1个字符。读入结束后,系统将自动在最后加'\0',并以str作为函数值返回。


2.输出

a.printf()可以输出字符串,并且可以根据占位符的个数来决定输出字符串的个数。

b.puts()可以输出一个字符串,而且是自动换行

printf()与puts

1)相同点,都可以输出字符串

2)不同点

printf()需要手动换行,可以多次输出字符串

puts()自动换行,只能输出一次字符串内容

c.const关键字

可以将变量变为只读,只可以在初始化时才可以改变变量的值,此变量就为常量。

  const int* p = &i;

//指针指向的值变为只读

  int* const p = &i;

//指针的值变为只读

d.指针数组(字符串数组)

数组中的元素是指针->指针又是字符串->字符串数组

1)保存多个字符串地址

2)定义指针数组

char* array[3]={ "guanyu","zhangfei" ,"liubei" };

3)遍历

for(int i = 0 ;i<3;i++){

printf("array[%d]:%s\n",i,array[i]);

}


e.字符串的比较 

注意:==不能判断两个字符串是否相等,判断的是两个字符串的内存地址,正常的做法应该是比较字符串中每一个字符的值是否相等(ASC码值比较)

3.C语言字符串函数库

a.#include <string.h>

b.字符串的复制 strcpy(str2,str)

参数1:目标字符串位置(复制到哪里)

参数2:源位置(字符串的来源)

c.字符串的拼接 strcat(str3,str)

参数1:第一个字符串

参数2:第二个字符串

将第一个字符串的内容与第二个字符串的内容拼接在一起,保存在第一个字符串中

d.字符串的长度 strlen(str)

求字符串的长度,不包含结束符

参数为:所求字符串

有返回值:返回字符串的长度


e.两个字符串比较 strcmp(str,str1)

根据ASC来进行比较,比较字符串中的每个字符是否相等(值),结果为两个字符串的差值,结果为0时,两个字符串相等。


作业:

1.模拟系统登录,提示输入用户名、密码,和数据库匹配,用户名:admin 密码:123 登录成功,否则登录失败,重新登录,输入密码错误三次,退出程序。

fgets … "admin\n”

2.使用键盘输入三个人的名字,保存并输出。


——————————

【Day 10】

C语言

一、宏

宏相当于字符串的替换操作

1.优点:可以代码更简单、更容易,避免大量使用。

2.宏定义

a.定义在函数的外面

b.格式:

#define PI 3.14

PI为宏的文件内容

在编译前将PI的内容替换成3.14


c.宏与全局变量的区别

1)宏相当于字符串的替换操作,内存中不存在

2)全局变量在内存中就存在的

d.相同点:

通常定义一个全局变量加const修饰符,全局变量的值是不可以修改的。

宏的内容也是不可以修改的


3.宏函数

#define MianJi(r) PI*r*r

宏函数只是文本,只是相当于做了内容替换的操作,注意参数是没有数据类型

4.在声明数组时也可以使用宏


5.#x 代表把x内容转换字符串

#define STR(x) #x

6.##x 代表将标识的内容与其它内容拼接在一起成为新的标识

#define QUANJU(x) g_##x

   int QUANJU(i) = 20;


7.C语言内部预定义的宏

     __LINE__ 当前行号

     __FILE__ 当前的文件名 

     __DATE__ 当前的日期

     __TIME__ 当前的时间

    __STDC__ 是否是C语言的标准 返回值为0或1

    __STDC__ ?"符合":"不符合";


二、宏的高级使用(条件编译)

 1.在代码中设置编译条件 根据编译条件进行代码的编译并运行。(跨平台)

 2.在编译文件的时候传入一个参数,根据参数就可以对代码进行有选择的编译。

gcc -DZHAOBENSHAN main3.c


1.条件指令

     #if 如果

     #ifdef 如果定义

     #ifndef 如果没定义

     #elif 如果 //else if

     #else 否则 与 #if 对应关系

     #endif 结束标识

     #undef 取消宏和#define 定义宏

2.代码中

#ifndef ZHAOBENSHAN

//普通用户版本

#else

//赵本山版本

#endif

3.传入参数

gcc -DZHAOBENSHAN main.c


练习:根据设备来生成不同的程序 输出以下内容:

iphone1~4s

iphone5~5s

iPad

iPadmini


大型软件开发:

1.操作步骤

    a.原来只有一个文件main.c 输入函数 输出函数 声明

    b.多人开发 将原文件拆分成三个文件,

分别为*.h、*.c、main.c

c.编译的时候

    1)分别编译不同的源文件,生成相应的目标文件 gcc -c input.c=>input.o

    2)可以将多个目标文件链接生成同一个可执行文件

gcc input.o main.o=>a.out

3)在main.c文件中,记的导入头文件


c.编译的时候

    3)在main.c文件中,记的导入头文件

    4).h文件中的条件编译解决的是重复声明的问题

#ifndef day11_3_input_h

#define day11_3_input_h

int inputNum();

#endif

5)在xcode中,Compile Sources解决链接问题的根本

总结:如果使用第三方的代码,要做两件事情,导入.h文件(声明),导入目标文件.o(实现)(*库)。

2.批量处理  make

可以使用make命令,一次性编译、链接多个文件的内容。(一次性执行多次命令)

    a.创建 makefile文件(任务清单)

    b.执行命令 make


Linux 软件安装 编译后.bin a.out 编译前.src make

3.头文件:以.h结尾的文件,是头文件。

  未使用内存空间的内容都可以放到头文件中,声明变量可能会有问题(因为开辟了存储空间),将要使用函数的声明放在头文件中,方便使用函数,如果函数声明变更,则只需要修改头文件的内容,而不需要修改源代码。

4.如果想在一个项目中共享全局变量,在使用的文件中,要使用extern关键字,声明变量,才可使用,并且可以得到全局变量的值。

5.全局变量前可以加static修饰符,该全局变量只能在当前文件中使用,static也可以修饰函数。加了static的变量,就是私有变量,加了static的函数,就是私有函数。

四、结构体

1.C语言中,可以使用结构体定义用户自定义类型,但结构成员类型可以不一样。

2.结构体的格式 

     struct{

成员;

     }变量名;

eg:

  struct{

    int age;

    char name[20];

                }student1,student2;//变量

最终版:

typedef struct {

    int age;//成员

    char name[20];

}Student2;//别名

结构体使用:

Student2 stu = {17,"lisi"};

    stu.age = 18;

   printf("stu name:%s age:%d\n",stu.name,stu.age);

3.如果结构体中的成员是字符串,是不能通过=进行赋值的,要使用

strcpy(student2.name,"zhangsan");

4.结构体的定义部分是不占用内存的,所以可以把结构体的定义放到头文件中,项目中的其它文件就可以使用该类型。

5.如果是基本数据类型,使用结构类型的变量.成员,可以操作该成员。

6.声明结构体类型的变量,占的空间为所有成员类型所占空间之和?边界对齐

  sizeof(Student2)

7.如果使用结构体变量赋值,相当于将结构体中每一个成员的值,都赋给新的结构体变量的成员。

练习:定义一个学生结构体,学号、姓名、年龄、性别(F、M),创建三个学生,键盘输入信息,并输出信息。(数组)

int array[3];

Student array[3];


——————————

【Day 11】

五、联合

1.联合的用法、语法和结构非常相似,但联合中所有成员分配的内存是同一块。(只能保存一个成员信息,联合的空间以最大成员所占的空间为值) 

2.联合可以用一块内存对应多种数据类型

3.联合与结构的区别,结构可以保存多个成员信息,而联合只能保存一个成员信息且最后一个。

typedef union {

    int age;

    char name[2];

}LianHe;

六、枚举

用字母来描述一组有规律的数值。

1.定义一个枚举

        enum{SPR,SUM,AUT,WIN};

2.枚举的默认值从0开始 ,每个值都是一个整型常量

3.只能在声明枚举的时候,修改枚举值

4.修改后的枚举值=上一枚举值加1

七、高级指针

1.堆内存的动态内存分配

    内存分为几个部分:

栈区 变量

代码区 字符串

全局区 全局变量

堆区 (自己创建、自己回收、变量、字符串)

    


     2.为了从堆中动态分配内存,要指定字节个数的空间,返回首地址,如果失败返回NULL(空)。

包含头文件stdlib.h,基本的内存操作都写好了。


3.malloc函数,可以从堆中分配指定的字节个数的空间,返回首地址,如果失败返回NULL。

4.calloc函数,会把分配到的所有字节都清0。

5.realloc函数,可以调整已经分配的空间,有两种情况,如果当前位置可以调整,在原位置调整,如果当前位置不可以调整,换一个新的位置。

6.free函数,用于释放(回收),从堆中分配的空间(内存。)

八、malloc函数

1.引入头文件stdlib.h

2.堆中没有变量名,只能通过指针的方式拿到内存中的数据(值)。

3.在使用堆内存指针的时候,最好使用const关键字修饰一下。

    int* const p = ……;

4.malloc函数可以分配堆内存,字节为单位的大小。

malloc(sizeof(int)*3)

5.if (point!=NULL) 语句避免内存分配失败,造成程序崩溃,非空(安全)验证。

6.堆内存使用完毕后,一定要释放。

  free(point);

九、calloc函数

1.引入头文件stdlib.h

2.堆中没有变量名,只能通过指针的方式拿到内存中的数据(值)。

3.在使用堆内存指针的时候,最好使用const关键字修饰一下。

int* const p = ……;

4.calloc函数可以分配堆内存,字节为单位的大小。

参数1 元素个数 参数2 每个元素所占空间大小

int* point = calloc(3, sizeof(int));

5.if (point!=NULL) 语句避免内存分配失败,造成程序崩溃,非空(安全)验证。

6.堆内存使用完毕后,一定要释放。

  free(point);

7.calloc函数分配内存时,会做清0操作。

十、realloc函数 调整内存空间

1.引入头文件stdlib.h

2.堆中没有变量名,只能通过指针的方式拿到内存中的数据(值)。

3.分配空间

参数1 调整哪个空间 

参数2 调整后的大小

realloc(point, sizeof(int)*5)

4.可能出现的情况

realloc(NULL, 5*sizeof(int));相当于malloc()

realloc(point, NULL);相当于free()

5.如果直接把新分配的地址,直接覆盖原来的地址,是有风险的,如果分配失败,将无法源来的地址,所以通常来讲会用一个新的变量,来保存新地址。分配成功后,再将新地址,赋值给老地址。(如果原来位置可以调整空间,就在原来位置调整)

6.如果原来位置不可以调整空间,程序会自动在新的位置创建空间,并且将原来的值移动到新的位置。

7.if (point!=NULL) 语句避免内存分配失败,造成程序崩溃,非空(安全)验证。point = newPoint;

8.堆内存使用完毕后,一定要释放。

  free(point);

十一、函数指针

1.用指针存储代码区函数的地址,所有的函数都是指针,函数名就是函数指针。2.函数指针可以做参数,可以传入。函数指针的参数类型和返回类型完全一致。->Block

eg:func();//普通的函数调用

   //函数是占内存的

   printf("func:%p &func:%p\n",func,&func);

//定义一个指针变量指向函数

//void返回值类型 void参数类型

  //void(*func_ptr)(void) 函数类型

  //func_ptr函数的变量名

  void(*func_ptr)(void) = func;

  void(*func_ptr2)(int) = func2;

  func_ptr();//通过函数指针调用函数

  func_ptr2(3);//通过函数指针调用有参函数

十二、void*

1.代表任意类型的指针,malloc分配堆内存时,由于无法确定内存存储类型,所以可以使用void*代表任意指针类型。

2.不能直接对void*指针进行*操作,可以进行类型转换,然后再进行*操作。

3.void*能进行加减操作,但以1字节为单位进行运算,所以说想向void进行加、减操作,最好先转换数据类型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值