您的位置:首页 > 移动开发 > Objective-C

某坑爹公司的笔记_Day06-Day11

2014-04-23 17:51 141 查看
这么久没更新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函数的调用形式如下:fgets(str,n,fp);此处,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进行加、减操作,最好先转换数据类型。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息