黑马程序员技术交流社区
标题: C语言基础知识要点回顾 [打印本页]
作者: yuanlingqi 时间: 2014-11-7 12:31
标题: C语言基础知识要点回顾
一、基础相关
1. #include 相当于导入文件内容。
2.main可以没有返回类型,没有参数,不写返回类型默认返回int,语法是不严格的。
3.C语言运行有两个步骤分别是,编译和链接,编译是将程序编译成目标代码,链接是将函数库的内容也加入到编译类,编译成功会生成.obj文件,链接完成后C程序才能执行。
4.C程序是从上往下执行,入口函数调用自定义方法必须要写在main之前或做声明。
- #include <stdio.h>
- int sum(int,int);
- int main(int argc, const char * argv[])
- {
- sum(10,3);
- return 0;
- }
- int sum(int a,int b){
- return a+b;
- }
复制代码 5.自定义函数通常写成.h和.c文件,类似一个是接口,一个是实现,main只需要包含.h文件即可,不可直接包含.c文件,会导致函数重复定义的错误:
- 5.1 main.c
- #include "firstC.h"
- int main(int argc, const char * argv[])
- {
- printf("sum结果为%d",sum(10,3));
- return 0;
- }
- 5.2firstC.c
- #include <stdio.h>
- int sum(int a,int b){
- return a+b;
- }
- 5.2firstC.h
- #ifndef FirstC_firstC_h
- #define FirstC_firstC_h
- int sum(int a,int b);
- #endif
复制代码 6. C语言的数据类型,大致归为四类,基本数据类型,空类型,指针,结构体类型。
注意:变量初始化的时候必须给默认值,否则会出现一个随机值,会引起不必要的异常。
作者: yuanlingqi 时间: 2014-11-7 12:36
二、指针相关
1.使用指针实现单个方法多个返回值:
- int sumAndMinus(int a,int b,int*p){
- *p=b-a;
- return a+b;
- }
- int main(int argc, const char * argv[])
- {
- int a = 10;
- int b = 20;
- int minus;
- int sum = sumAndMinus(a,b,&minus);
- printf("%d,%d",minus,sum);
- }
复制代码 2、在同个编译环境下,一个指针变量占用的内存空间是固定的。
3、指针和数组有共性也有区别,主要区别如下:
- char s[7]="iloveyo";//字符串变量
- char *p = "iloveyou";//字符串常量
复制代码
作者: yuanlingqi 时间: 2014-11-7 12:43
三、指向函数的指针
1.函数名就是函数地址
2.声明一个指向函数的指针变量
- int sumAndMinus(int a,int b,int*p){
- *p=b-a;
- return a+b;
- }
- int (*p)(int a,int b);
- p = sumAndMinus;
- (*p)(5,6);//等价于p(5,6);
复制代码 3.指向函数的指针的用途
代码不变,算法变动的情况下,需要用到指向函数的指针,可以将函数当做参数实现相应算法。
功能和Lambdas以及和oc中的block有点类似:
- int sum(int a,int b){
- return a+b;
- }
- int minus(int a,int b){
- return a-b;
- }
- int caculate(int a,int b,int (*p)(int,int)){
- return p(a,b);
- }
- int main(int argc, const char * argv[])
- {
- int sumResult = caculate(20,10,sum);
- int minusResult = caculate(20,10,minus);
- printf("sumResult=%d,minusResult=%d",sumResult,minusResult);
- }
复制代码
作者: yuanlingqi 时间: 2014-11-7 12:49
四、预处理指令1. 预处理指令包括:宏定义,文件包含和条件编译:
1.1、宏定义
- //宏定义用来定义常量
- #define NUM 6
- //带参数的宏定义,简单的计算函数尽量用宏定义替代,效率更高
- #define mul(a,b) ((a)*(b))
- int main(int argc, const char * argv[])
- {
- int mulResult = mul(20,10)/mul(2,2);
- printf("mulResult=%d",mulResult);
- }
复制代码 1.2 条件编译:
- #define NUM 0
- int main(int argc, const char * argv[])
- {
- // 条件编译,效率更高
- #if NUM==0
- printf("NUM == 0");
- #elif NUM > 0
- printf("NUM > 0");
- #else
- printf("NUM < 0");
- #endif
- return 0;
- }
复制代码 根据宏来进行条件编译:
- //#define NUM 0
- int main(int argc, const char * argv[])
- {
- //如果定义过宏NUM则编译,否则编译另一段
- //#if defined(NUM)等价于下面的写法
- #ifdef NUM
- printf("宏已经定义");
- #else
- printf("宏未定义");
- #endif
- return 0;
- }
复制代码 1.3 文件包含
避免重复包含很重要,系统自动帮我们实现了这个代码,它是利用条件编译和宏定义来实现的
//若宏未定义则定义该宏,并将文件包含进来,若已定义则不再包含该文件
#ifndef FirstC_firstC_h
#define FirstC_firstC_h
int sum1(int a,int b);
#endif |
作者: 易拉罐 时间: 2014-11-7 12:51
路过,顺便也学习了一下。。
作者: yuanlingqi 时间: 2014-11-7 14:15
五、其他要点
1.变量的存储类型:
a.自动变量-堆栈-生命周期短-运行时局部变量
b.静态变量-普通内存-生命周期相对长-程序运行前创建全局变量和static修饰的局部变量(static改变的是生命周期,不变的是作用域)
c.寄存器变量-寄存器-被register修饰的自动变量称为寄存器变量-迅速创建迅速销毁,只限于int,char和指针类型变量
2.extern函数
外部函数:如果在当前文件定义的函数允许其他文件调用,访问,该函数就是外部函数,默认为外部函数,不允许重复同名。
内部函数:如果不允许其他文件调用访问,则称为内部函数。
//完整声明一个函数,需要用到extern关键字,表示引用一个外部函数,可以省略,默认就是
extern void test();
int main(int argc, const char * argv[])
{
test();
return 0;
}
用static 修饰的全局变量,就是内部变量,将无法被外部类访问。
作者: yuanlingqi 时间: 2014-11-7 14:35
六、其他一些要点笔记
1、指向结构体的指针,利用指针访问结构体成员,(*p).age等价于p->age
2、枚举类型,通常用来声明一组常量,枚举会被当做整数类型处理。
- enum season{spring,summer,autumn,winter};
- enum season se=summer;
- 遍历枚举的方法
- for(se=spring;se<winter;se++)printf("%d\n",se);
复制代码 3、typedef给数据类型起别名重命名int类型
typedef int Integer;
重命名指针类型
typedef char* String;
//#define Integer int
重命名结构体
typedef struct Point{float x;float y} Mypoint;
Mypoint pt={1.1,2.2};
printf("%.2f,%.2f\n",pt.x,pt.y);
重命名结构体指针类型
typedef struct Point{float x;float y}* Mypoint;
struct Point pt={1.1,2.2};
Mypoint pt2 = &pt;
printf("%.2f,%.2f\n",pt2->x,(*pt2).y);
通常会先重命名结构体类型,然后再重命名结构体指针类型
typedef struct {float x;float y}Point;
typedef Point* MyPoint;
Point pt={1.1,2.2};
MyPoint pt2 = &pt;
printf("%.2f,%.2f\n",pt2->x,(*pt2).y);
重命名枚举类型
typedef enum {spring,summer,autumn,winter} Season;
Season ss = spring;
重命名指向函数的指针
typedef int (*mysum)(int,int);
mysum pp = sumo;
printf("%d\n",(*pp)(5,6));
4、typedef和宏定义的区别,宏定义仅仅是替换
作者: doudou33420 时间: 2014-11-7 14:35
支持一下 总结的很细
我对函数指针一直没什么理解, 感觉和直接使用函数没区别.. (作为参数传递?)
static 可以间接被外部访问(我是这么理解)
一个类定义了static全局变量 第二个类#import它 在第二个类中 就可以直接访问此变量并且可以给它赋值
作者: yuanlingqi 时间: 2014-11-7 15:17
若不是这几年流行一个概念叫函数编程,我也不会留意到函数指针,因为指向函数的指针,向来是不作为C语言基础内容的。你有兴趣可以了解下函数编程,目前是各大流行语言力捧的编程方式,未来会越来越重要。
作者: doudou33420 时间: 2014-11-7 15:19
恩 放到以后研究
作者: breaking1800 时间: 2014-11-7 15:37
总结得很好啊!
作者: 飞奔的坦克 时间: 2014-11-7 21:21
不错。。。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |