C语言-基础总结(48600字)

来源:m.ttfanwen.com时间:2016.4.18

一、第一个c语言程序

1)真个程序的运行过程 2015-2-27 21:45:00

2)总结常见文件的拓展名

.c是C语言源文件,在编写代码的时候创建 .o是目标文件,在编译成功的时候产生 .out是可执行文件,在链接成功的时候产生

3)总结clang指令

编译:cc –c xxx.c

链接:cc xxx.o

编译、链接:cc xxx.c

运行可执行文件:./a.out

C语言基础总结

4)开发中会遇到哪些错误?如何解决? 语法错误,可以通过编译器的报错信息解决 逻辑错误,需要耐心调试程序

5)学习建议

学编程并不是学英文

程序的可读性

初学者不要过于寻根问底

6)习题

用2种不同的代码方式输出下面的图案 ************

** itcast **

************

#include <stdio.h>

int main()

{

printf("************\n** itcast **\n************\n");

printf("************\n");

printf("** itcast **\n");

printf("************\n");

return 0;

}

二、关键字、标示符、注释

一、关键字

1)什么是关键字

关键字就是C语言提供的有特殊含义的符号,也叫做“保留字” 2015-2-27 21:45:00 C语言一共提供了32个关键字,这些关键字都被C语言赋予了特殊含义 auto double int struct break else long switch

case enum register typedef char extern return union

const float short unsigned continue for signed void

default goto sizeof volatile do if while static

大致浏览一遍即可,不用去百度每个关键字的作用,这些关键字以后会经常用到的,到时候你想不记住都难

2)关键字的特征

全部都是小写

在开发工具或者智能文本编辑工具中会显示特殊颜色。默认情况下,C语言中的所有关键字在Xcode中都会显示紫褐色

二、标示符

1.什么是标识符

? 标识符就是在程序中自定义的一些符号和名称。要跟关键字区分开来:关键

2.命名

?

? 字是C语言默认提供的符号,标识符是程序员自定义的 命名规则 o 命名规则(一定要遵守) o 只能由26个英文字母的大小写、10个阿拉伯数字0~9、下划线_组成 o 严格区分大小写,比如test和Test是2个不同的标识符 o 不能以数字开头 o 不可以使用关键字作为标识符 命名规范

o 尽量起个有意义的名称,比如一个完整的英文单词,别人一看这个名称就能能知道这个标识符的作用。如果不懂英文,你也可以用拼音,尽量不要起像abcde、sfsdfsdf等这类看起来没有意义的名称

o 如果标识符中含有多个单词,可以使用驼峰标识(除开第一个单词,后面每个单词的首字母都是大写):firstName、myFirstName,或者

使用下划线_来连接:first_name、my_first_name

3.练习

? 判断对错

o test1 Mike2jack My_tExt _test

o test!32 haha(da)tt 哈哈_text 123haha o 78text a _123 _

三、注释

注释的嵌套现象

1.单行注释可以嵌套单行注释、多行注释 // 哇哈哈 // 呵呵呵

// /* fsdfsdf */ // sdfsdfsd

2.多行注释可以嵌套单行注释

/*

// 作者:MJ

// 描述:第一个C语言程序

作用:这是一个主函数,C程序的入口点 */

3.多行注释不能嵌套多行注释

/* 哈哈哈

/*嘻嘻嘻*/

呵呵呵 */

4.下面的写法是错误的

// /*

哈哈哈

*/

三、数据类型、常量、变量

一、数据类型 2015-2-27 21:45:00

二、常量

1> 整型常量(int)

? 包括了所有的整数,比如6、27、109、256、-10、0、-289等

2> 浮点型常量(float\double)

浮点型常量分为double和float两种数据类型

C语言基础总结

? double:双精度浮点型,其实就是小数。比如5.43、-2.3、0.0等(注意,0.0也算是个小数)

? float:单精度浮点型,也是小数,比double的精确程度低,也就是说所能表示的小数位数比较少。为了跟double区分开来,float 型数据都是以f结尾的,比如5.43f、-2.3f、0.0f。需要注意的是,绝对不能有10f这样格式的,编译器会直接报错,只有小数才允许加上f。

3> 字符常量(char)

? 将一个数字(0~9)、英文字母(a~z、A~Z)或者 其他符号(+、-、!、?等)用单引号括起来,这样构成的就是字符常量。比如'6'、'a'、'F'、'+'、'$'等。 ? 注意:单引号只能括住1个字符,而且不能是中文字符,下面的写法是错误的:'abc'、'123456'、'男'

4> 字符串常量

? 将一个或者多个字符用双引号("")括起来,这样构成的就是字符串常量。比如"6"、"男"、"哇哈哈"、"abcd"、"my_car4",其实printf("Hello World");语句中的"Hello World"就是字符串常量。

? 那究竟6、'6'、"6"在用法上有什么区别呢?这个先不作讨论,以后会介绍。

三、常量

不使用其他变量形成的参数互换

#include <stdio.h>

int main()

{

int a = 10;

int b = 20;

a = b - a;

b = b - a;

a = a + b;

printf("a = %d,b = %d\n",a,b);

return 0; }

作业

一、改错题

1.

? #include <stdio.h>

?

? int main()

? {

? printf("Hello!\n");

? return 0;

? }

?

? int main()

? {

? printf("World!\n");

? return 0;

? }

? ======================================== 2015-2-27 21:45:00

? // 错误原因:不能有2个main函数,删掉其中一个就可以运行了 ?

2.

? #include <stdio.h>

?

? int mian() // main错写成了mian ?

?

?

?

?

?

?

3.

?

?

?

?

?

?

? { printf(Hello!\n); printf('Hello!\n'); // 两句代码都是错误的,应该是"Hello!\n" return 0; } #include <stdio.h> int main // main后面少了个括号 { prinft("Hello World!\n“); // printf错写成了prinft // 最后面的双引号用了中文符号 return 0 // 0后面少了个分号

? }

?

4.

? #include <stdio.h> ?

?

?

?

?

?

?

?

?

?

?

?

5.

?

? int main() { int a = 10; int b = 20; int a = b; // 重复定义了变量a return o; // 将0写成了字母o } #include <stdio.h>

? int main()

? {

? int a = b;

? int b = 20; // 应该将变量b定义在变量a的前面 ?

? double 2b = 1.55;

能以字母或下划线开头

?

? char c1 = 'a';

?

? char c2 = A;

为A是一个变量名

?

? return 0;

? }

?

二、编程题

1.C程序是由什么构成的? // 变量名是标识符的一种,不能以数字开头,只// 字母A应该用单引号括住:'A',不然编译器会认

? 函数

2.C程序的源文件拓展名是什么?

? .c或者.C

3.C程序的源文件能直接运行么?为什么?

? 不能,因为不是机器语言

4.C程序从开发到运行需要哪些步骤?

? 1> 编写.c源文件

? 2> 编译.c源文件为.o目标文件

? 3> 链接.o目标文件为可执行文件

? 4> 运行可执行文件

5.拓展名为.c、.o、.out分别是什么文件?在C程序开发的哪个阶段产生的?

? 编程源文件、目标文件、可执行文件

? 在编写程序阶段,编译阶段,链接阶段

6.下面这段程序是否能独立运行成功?

#include <stdio.h>

int test()

{

printf("哈哈哈哈\n"); return 0;

}

? 不可以,没有main函数

7.下面这段程序能否运行成功?

int main()

{

}

? 可以运行成功,但是编译器会有警告信息,因为缺少了#include <stdio.h>

8.编写程序在屏幕上输入下列内容

*

***

*****

*******

? #include <stdio.h>

?

? int main()

? {

? printf("*\n***\n*****\n*******\n"); printf("哈哈哈哈\n"); return 0;

?

? return 0;

? }

9.说出下列程序的输出结果(不要借助终端指令) #include <stdio.h>

int main()

{

int a = 20;

int score = a + 100;

printf("%d\n", score);

{

int score = 50;

{

score = 10;

printf("%d\n", score);

}

a = 10;

}

{

score = a + 250;

int score = 30;

printf("%d", score);

}

printf("%d\n", score);

return 0;

}

? 120

? 10

? 30260

? //大括号外面有score括号里面也有的情况,改变的是括号里面的值,括号里面直接调用score那么用的就是外面的值,改变的也是外面的值.全局变量也遵循这一规律。

四、scanf函数

一、内存分析

1.所占用字节数跟类型有关,也跟编译器环境有关 2015-2-27 21:45:00

?

2.变量实例

? int b = 10;

? int a = 20;

? 内存由大到小寻址,优先分配内存地址较大的字节给变量。b的内存地址比a大

? 每个变量都有地址:第一个字节的地址就是变量的地址

3.查看内存地址:

? int a;

? printf("a的地址是:%p\n", &a);

4.注意在变量未经初始化之前,不要尝试使用变量的值

? int a;

? printf("a的值是:%d\n", a);

上面的写法是不建议的

二、scanf函数

1.简介

? 这也是在stdio.h中声明的一个函数,因此使用前必须加入#include <stdio.h>。调用scanf函数时,需要传入变量的地址作为参数,scanf函数会等待标准输入设备(比如键盘)输入数据,并且将输入的数据赋值给地址对应的变量

2.简单用法

int age;

scanf("%d", &age);

? scanf函数时,会等待用户的键盘输入,并不会往后执行代码。scanf的第1个参数是"%d",说明要求用户以10进制的形式输入一个整数。这里要注意,scanf的第2个参数传递的不是age变量,而是age变量的地址&age,&是C语言中的一个地址运算符,可以用来获取变量的地址

? 输入完毕后,敲一下回车键,目的是告诉scanf函数我们已经输入完毕了,scanf函数会将输入的值赋值给age变量

3.其他用法:用scanf函数接收3个数值,每个数值之间用中划线-隔开

? scanf("%d-%d-%d", &a, &b, &c);

? 3个%d之间是用中划线-隔开的,因此我们在每输入一个整数后都必须加个中划线-,比如这样输入,不然在给变量赋值的时候会出问题

4.注意:数值之间的分隔符是任意的,不一定要用中划线-,可以是逗号、空格、星号*、井号#等等,甚至是英文字母

? // 逗号,

? scanf("%d,%d,%d", &a, &b, &c); // 输入格式:10,14,20

? // 井号#

? scanf("%d#%d#%d", &a, &b, &c); // 输入格式:10#14#20

? // 字母x

? scanf("%dx%dx%d", &a, &b, &c); // 输入格式:10x14x20

5.用scanf函数接收3个数值,每个数值之间用空格隔开

? scanf("%d %d %d", &a, &b, &c);

? 3个%d之间是用空格隔开的,我们在每输入一个整数后必须输入一个分隔符,分隔符可以是空格、tab、回车

6.注意

? scanf的第一个参数中不要包含\n,比如scanf(“%d\n”, &a); 这将导致scanf函数无法结束

7.习题:提示用户输入两个整数n,然后计算并输出两个整数的和

? #include <stdio.h>

?

? int score = 10;

?

? int sum(int ,int);

?

? int main()

? {

? int a;

?

? int b;

?

? printf("请输入两个值,并且以+号隔开\n"); ?

? scanf("%d+%d",&a,&b);

?

? int c = sum(a,b);

?

? printf("这两个值的和是%d\n",c);

?

? return 0; ? }

?

? int sum(int a,int b) ? {

? return a + b; ? }

?

五、基本运算

一、算数运算

C语言一共有34种运算符,包括了常见的加减乘除运算

1.加法运算+

? 除开能做加法运算,还能表示正号:+5、+90

2.减法运算-

? 除开能做减法运算,还能表示符号:-10、-29

3.乘法运算*

? 注意符号,不是x,而是*

4.除法运算/

? 注意符号,不是÷,也不是\,而是/ 2015-2-27 21:45:00

? 整数除于整数,还是整数。1/2的值是0,这个并不是二分之一

5.取余运算%

? 什么是取余:两个整数相除之后的余数

? %两侧只能是整数

? 正负性取决于%左侧的数值

6.注意点

? 自动类型转换 //自动类型转换还是自动类型提升,主要看定的时候定的类型是否比实际的类型要大,大则提升,小则转换.转换的方式为先计算后转换 o int a = 10.6;

o int b = 10.5 + 1.7;

o 自动将大类型转换为了小类型,会丢失精度

? 自动类型提升

o int b = 10.5 + 10;

o 将右边的10提升为了double类型 //这里的计算中有一个double类型了另外一个如果不是会自动提升为double类型,但是计算完了之后还是会按照定义的int类型进行取值

o double b = 1.0 / 2;

o 解决除法的精度问题 //本来是两个整数的运算,其中一个故意写成double形式,这样就能让另外一个整数自动提升为double形式 ? 强制类型转换

o double a = (double)1 / 2;

o double b = (double)(1 / 2);//这两个区别在于一个强制转换一个数,另一个是全职转换了结果.但是如果只是转换了结果还是会以int形式输出

7.运算顺序

? 表达式

? 结合性(结合方向):2+3+4

? 优先级:5+4*8-3

8.习题

? 当?是什么运算符时,不论整型变量a的值怎么变,结果c都不超过10:int c = a?10;

o %

? 提示用户输入两个整数,并输出两个整数的平均数

o #include <stdio.h>

o

o double average(int ,int);

o

o int main()

o {

o printf("请输入要求平均值的两个整数,并且以下划线分开\n"); o

o int a , b;

o

o scanf("%d_%d",&a,&b);

o

o printf("这两个数的平均值是%f\n",average(a,b));

o

o return 0;

o }

o

o double average(int a, int b)

o {

o return ((double)a + b)/2;

o }

? 提示用户输入一个时间的秒数,比如500秒就输入500,然后输出对应的分钟和秒,比如500s就是8分钟20秒

o #include <stdio.h>

o

o int main()

o {

o printf("请输入秒数\n");

o

o int sec;

o

o int min;

o

o int hour; o

o scanf("%d",&sec); o

o

o

o

o

o

o

o

o

o

o

o

o

o

二、赋值运算 if (sec>3600) { hour = sec / 3600; min = (sec % 3600)/60; sec = sec % 60; printf("这一共是%d小时%d分钟%d秒\n",hour,min,sec); }else{ min = sec / 60; sec = sec % 60; printf("这一共是%d分钟%d秒\n",min,sec); } return 0; }

1.简单赋值

? int a = 10 + 5;的运算过程

? a = b = 10;的运算过程

? 等号左边不能是常量,比如10 = 11;

2.复合赋值

// 复合赋值运算符

? a += 5; // a = a + 5;

? a *= 5; // a = a * 5;

? a += 5 + 6 + 4; // a = a + (5 + 6 + 4);

三、自增自减

1.简单使用

? ++ 自增运算符。如a++,++a,都等价于a = a+1 ? 自减运算符。如a--,--a,都等价于a = a-1 ? 5++是错误的

2.++a和a++的区别

? int a = 10;

? a++; ++a;

? int b = a++ == 10; int b = ++a == 11;//a++是先赋值后加,相当于把10给了b然后自己变成11.++a就是把a先变成11然后把11给b。

四、sizeof

1.作用

? 用来计算一个变量或者一个常量、一种数据类型所占的内存字节数。

2.基本形式

? sizeof( 变量\常量 ) //sizeof(a); sizeof(10); sizeof('A');

? sizeof 变量\常量 //sizeof a; sizeof 10; sizeof 'a';

? sizeof( 数据类型 ) //sizeof(int);

? 不能是sizeof 数据类型 //sizeof int;这样是不对的

五、关系运算(比较运算)

1.真假

? 在C语言中,条件成立称为“真”,条件不成立称为“假”,因此,判断条件是否成立,就是判断条件的“真假”。

? 怎么判断真假呢?C语言规定,任何数值都有真假性,任何非0值都为“真”,

只有0才为“假”。也就是说,108、-18、4.5、-10.5等都是“真”,0则是“假”。

2.使用注意

? 关系运算符中==、!=的优先级相等,<、<=、>、>=的优先级相等,且前者的优先级低于后者:2==3>1

? 关系运算符的结合方向为“从左往右”: 4>3>2

? 关系运算符的优先级小于算术运算符:3+4>8-2

3.练习

? 3 > 4 + 7 // 0

? (3>4) + 7 // 7

? 5 != 4 + 2 * 7 > 3 == 10 // 0

?

六、逻辑运算

1.&& 逻辑与

? 使用格式

o “条件A && 条件B”

? 运算结果

o 只有当条件A和条件B都成立时,结果才为1,也就是“真”;其余情况的结果都为0,也就是“假”。因此,条件A或条件B只要有一个不成立,结果都为0,也就是“假。

? 运算过程:总是先判断A是否成立

o

o

? 注意

o

o 如果条件A成立,接着再判断条件B是否成立:如果条件B成立,“条件A && 条件B”的结果就为1,即“真”,如果条件B不成立,结果就为0,即“假” 如果条件A不成立,就不会再去判断条件B是否成立:因为条件A已经不成立了,不管条件B如何,“条件A && 条件B”的结果肯定是0,也就是“假” 若想判断a的值是否在(3, 5)范围内,千万不能写成3<a<5,因为关系运算符的结合方向为“从左往右”。 比如a为2,它会先算3<a,也就是3<2,条件不成立,结果为0。再与5比较,即0<5,条件成立,结果为1。因此 3<a<5的结果为1,条件成立,也就是说当a的值为2时,a的值是在(3, 5)范围内的。这明显是不对的。正确的判断方法是:(a>3) && (a<5) C语言规定:任何非0值都为“真”,只有0才为“假”。因此逻辑与也适用于数值。比如 5 && 4的结果是1,为“真”;-6 && 0的结果是0,为

“假”

2. || 逻辑或

? 使用格式

o “条件A || 条件B

? 运算结果

o 当条件A或条件B只要有一个成立时(也包括条件A和条件B都成立),结果就为1,也就是“真”;只有当条件A和条件B都不成立时,结果才为0,也就是“假”。

? 运算过程:总是先判断A是否成立

o 如果条件A成立,就不会再去判断条件B是否成立:因为条件A已经成立了,不管条件B如何,“条件A || 条件B”的结果肯定是1,也就是“真”

o 如果条件A不成立,接着再判断条件B是否成立:如果条件B成立,“条件A || 条件B”的结果就为1,即“真”,如果条件B不成立,结果就为0,即“假”

? 注意

o C语言规定:任何非0值都为“真”,只有0才为“假”。因此逻辑或也适用于数值。比如 5 || 4的结果是1,为“真”;-6 || 0的结果是1,为“真”;

0 || 0的结果是0,为“假”

3. ! 逻辑非运算符

? 使用格式

?

?

4.优先级

?

?

? o “! 条件A” 运算结果 o 其实就是对条件A进行取反:若条件A成立,结果就为0,即“假”;若条件A不成立,结果就为1,即“真”。也就是说:真的变假,假的变真。 注意 o 可以多次连续使用逻辑非运算符:!(4>2)结果为0,是“假”,!!(4>2)结果为1,是“真”,!!!(4>2)结果为0,是“假” o C语言规定:任何非0值都为“真”,只有0才为“假”。因此,对非0值进行逻辑非!运算的结果都是0,对0值进行逻辑非!运算的结果为1。!5、!6.7、!-9的结果都为0,!0的结果为1 逻辑运算符的优先级顺序为: 小括号() > 负号 - > ! > 算术运算符 > 关系运算符 > && > || 表达式!(3>5) || (2<4) && (6<1) :先计算 !(3>5)、(2<4)、(6<1),结果为1,式子变为1 || 1 && 0,再计算1 && 0,式子变为1 || 0,最后的结果为1 表达式3+2<5||6>3 等价于 ((3+2) < 5) || (6>3),结果为1

? 表达式4>3 && !-5>2 等价于 (4>3) && ((!(-5)) > 2) ,结果为0

七、三目运算符

? 格式

o 条件?数值1:数值2

? 运算结果

o 条件成立就输出数值1,条件不成立就输出数值2

? 例:

o

流程控制

一、流程控制

1. 顺序结构:默认的流程结构。按照书写顺序执行每一条语句。 2015-4-24 7:27:00

2.选择结构:对给定的条件进行判断,再根据判断结果来决定执行哪一段代码。

3.循环结构:在给定条件成立的情况下,反复执行某一段代码。

二、选择结构 - if

1. 简单使用

? if (表达式) 语句1; //直接在后面写语句,可以不用加大括号

o if(count>50) 开班; 上课;

? if(表达式) 语句1; else 语句2;

o f(count>50) 开班;

o else 不开班;

? if(表达式) { }

o if(count>50) {开班; 布置课室;}

C语言基础总结

o else {} o { }的作用域 ? if -else if-else ?

?

?

?

?

?

?

总结

?

?

?

?

? o if(a==0) else if (a>0) else o 特点:只有一个括号会被执行 复合条件 o 上课时间的取值范围(9~12 || 14 ~17) 陷阱 if(a!=0) { a不是0;} else {a是0;} if (a); { } if (a=0) a == 0; if (10) int a = 9; /* 1.if的第1种结构 if(条件) { 语句1;

? 语句2; ? ...... ? }

?

? 2.if的第2种结构 ? if(条件1) ? {

? 语句1; ? 语句2; ? ...... ? }

? else

? {

?

? }

?

? 3.if的第3种结构 ? if(条件1) ? {

? 语句1; ? 语句2; ? ...... ? }

? else if(条件2) ? {

?

? }

? else if(条件3) ? {

?

? }

? else if(条件4) ? {

?

? }

? else ? {

?

? }

?

? 4.if的第4种结构 ? if (条件) ?

?

注意

?

?

?

?

?

?

?

?

?

?

?

? 语句1; */ #include <stdio.h> int main() { /* if (0) { printf("A\n"); } else {

? printf("B\n");

? }*/

?

? /*

? int a = 1044343;

?

? 比较大小时,常量值放左边,变量放右边,防止少写一个等号变成赋值语句

? //if (a = 0)

? if (0 == a)

? {

? printf("a等于0\n");

? }

? else

? {

? printf("a不等于0\n");

? }*/

?

? /*

? int a = 10;

?

? // 注意赋值运算符,不要写成两个= ? a = 15;

?

? printf("%d\n", a);

? */

?

? /* if语句后面不要写;

? if ( 5>6 );

? {

? printf("A\n");

? }*/

?

?

? /*

? if (10 > 6)

? {

? int a = 5;

? }

?

? printf("%d\n", a);

? */

?

? // 下面的代码是错误的:作用域不明确

? if (10 > 6)

? int a = 5;

? // 如果要在if后面的语句中定义新的变量,必须用大括号{} ? //printf("%d\n", a);

?

? /*

? 书写格式

? int a = 10;

? if (a>10) {

?

? } else if (a>5) {

?

? } else {

? ? } ? ? if () ? ? ? ? ? ? ? ? ? ? ? ? ? } 练习 { } else if () { } else { }*/ return 0;

? 输入一个整数day代表星期几,根据day的值输出对应的星期几,比如day==1,就输出“星期一”

o #include <stdio.h>

o

o int main()

o {

o printf("输入一个整数\n");

o

o int day;

o

o scanf("%d",&day);

o

o if (day == 1) {

o printf("星期一\n");

o }else if(day == 2){

o printf("星期二\n");

o }else if(day == 3){

o printf("星期三\n");

o }else if(day == 4){

o printf("星期四\n");

o }else if(day == 5){

o printf("星期五\n");

o }else if(day == 6){

o printf("星期六\n");

o }else if(day == 7){

o printf("星期日\n");

o }else if(day>7 || day < 1){

o printf("输入有误\n");

o }

o

o return 0;

o }

? 输入一个整数month代表月份,根据月份输出对应的季节。 ? 春季:3、4、5

? 夏季:6、7、8

? 秋季:9、10、11

? 冬季:12、1、2

o #include <stdio.h>

o

o int main()

o {

o printf("输入一个整数\n");

o

o int month;

o

o scanf("%d",&month);

o

o if (month>=3&&month<=5) {

o printf("春季\n");

o }else if(month>=6&&month<=8){

o printf("夏季\n");

o }else if(month>=9&&month<=11){ o printf("秋季\n");

o }else if(month==12||month==1||month == 2){ o printf("冬季\n");

o }else if(month>12 || month < 1){

o printf("输入有误\n");

o }

o

o return 0;

o }

o

? 输入一个整数score代表分数,根据分数输出等级(A-E)(用两种方式) ? A:90~100

? B:80~89

? C:70~79

? D:60~69

? E:0~60

o 1.判断等级 (性能最高)

o if (score>=90 && score<=100) { // [90, 100]

o printf("A\n");

o } else if (score>=80) { // [80, 89]

o printf("B\n");

o } else if (score>=70) { // [70, 79]

o printf("C\n");

o } else if (score>=60) { // [60, 69]

o printf("D\n");

o } else { // (-∞, 59]

o printf("E\n");

o }

o

o 2.性能中等

o if (score>=90 && score<=100) { // [90, 100] o printf("A\n");

o } else if (score>=80 && score<=89) { // [80, 89] o printf("B\n");

o } else if (score>=70 && score<=79) { // [70, 79] o printf("C\n");

o } else if (score>=60 && score<=69) { // [60, 69] o printf("D\n");

o } else { // (-∞, 59]

o printf("E\n");

o }

o

o 3.性能最差

o if (score>=90 && score<=100) { // [90, 100] o printf("A\n");

o }

o

o if (score>=80 && score<=89) { // [80, 89] o printf("B\n");

o }

o

o if (score>=70 && score<=79) { // [70, 79] o printf("C\n");

o }

o

o if (score>=60 && score<=69) { // [60, 69] o printf("D\n");

o }

o

o if (score<=59) { // (-∞, 59]

o printf("E\n");

o }

三、选择结构 switch

? 简单使用

o

? 举例

o

o

o

o

o

o

o

o

o

o

o

o

oswitch(表达式) { case 数值1: break; … default: break;} int a = 10; switch (a) { case 0: printf("这是一个0"); break; case 5: printf("这是一个5"); break; case 10: printf("这是一个10"); break; default: printf("什么也不是");

o break;

o }

? 简述break的作用:break:退出整个switch语句,如果case后面没有break,就会执行后面所有case中的语句,直到遇到break为止

? 在case中定义变量:如果要在case后面定义新的变量,必须用大括号{}包住

o switch (c) {

o case '+':

o {

o int sum = a + b;

o printf("和是%d\n", sum);

o break;

o }

o

o case '-':

o {

o int minus = a - b;

o printf("差是%d\n", minus);

o break;

o }

o }

o

? if和switch的对比

o 很多情况可以互换

o if用得比较多,比较灵活,switch只能某个单值

四、循环结构 while

1.简单实用

? 连续printf(“俯卧撑”)20次;

? while(表达式) { }

? continue:输出5次休息一下 //直接结束这一次循环体,进入下一次循环 ? break的使用:某次的时候停止循环 //直接结束整个while循环

2.特点

只有条件成立才会执行循环体

3.习题

1>提示用户输入一个正整数,计算1+2+3+4……+n的和

? #include <stdio.h>

?

? int main()

? {

? // 定义变量保存用户输入的整数 ? int n = 0; // 一定要初始化 ?

? while (n <= 0)

? {

? // 1.提示输入

? printf("请输入一个正整数:\n"); ?

? // 2.接收输入

? scanf("%d", &n);

? }

?

? // 3.计算

? // (1 + n) * n / 2;

? // 定义变量保存和

? int sum = 0;

? int number = 0; // 默认被加的数值 ? while (number < n)

? {

? number++;

? sum += number; // 累加 ? }

?

? printf("%d\n", sum);

? return 0;

? }

2. 提示用户输入一个正整数n,计算1-2+3-4+5-6+…+n的和

? #include <stdio.h>

?

? int sum(int n)

? {

? int i = 0;

? int sum1 = 0;

? while (i <=n ) {

?

? if (i%2==0) {

? sum1 = sum1 -i; ? i++;

? continue; ? }

?

? sum1 = sum1 + i; ? i++;

? }

?

? return sum1;

? }

?

?

?

? int main()

? {

? printf("请输入一个正整数\n"); ?

? int n;

?

? scanf("%d",&n); ?

? int sum1 = sum(n); ?

? printf("结果是%d\n",sum1); ?

? return 0;

? }

?

4.陷阱

? while(条件);//这样会造成死循环

五、循环结构 do while 1. 特点:一定会执行一次循环体

2.while 和 do while的对比

? while和do while循环对比

? int i=0;

while(i<0){

i++;

}

?

? int i=0;

do{

i++;

} while(i<0);

? while和do-while的区别

? 1.很多情况下,while和do while可以互换

?

? 2.while特点:如果一开始的条件不成立,永远不会执行循环体

? do while特点:不管一开始的条件是否成立,至少会执行一次循环体 ?

? 3.最好使用while

六、循环结构 for

1.简单实用

? 运行过程

o for (语句1; 条件; 语句2)

o {

o 循环体

o }

o

o 语句1:初始化语句

o 语句2:增量语句(执行完循环体后再执行的语句)

o

o 1.for一开始就会执行一次语句1(整个for循环只会执行一次) o 2.判断条件是否成立,如果条件成立,就会执行一次循环体,然后就会执行语句2,再次判断条件是否成立

? 初始化语句等可以是多句(把printf放到for的括号中)/*

o "做俯卧撑"50次

o */

o /*

o int count = 0;

o

o for ( ; count < 50; )

o {

o printf("做俯卧撑\n");

o count++;

o }*/

o

o /*

o for (int count = 0; count < 50; ) o {

o printf("做俯卧撑\n");

o count++;

o }*/

o

o /*

o for (int count = 0; count < 50; count++) o {

o printf("做俯卧撑\n");

o }*/

o

o /*

o for (int count = 0; count < 50; printf("做俯卧撑\n"),printf("哈哈哈\n"),count++)

o {

o

o }*/

o

2.陷阱

? 死循环 for(;;);

? for循环体内部变量的作用域;//{}内定义的变量只能在{}内使用

? 作用域混淆

o for (int i = 0; i<5; i++) int a = 10;

3.while循环和for循环的比较

? 可以互换

? for循环的变量可以及时回收

4.练习

? 提示用户输入一个正整数n,如果n5,就输出下列图形,其他n值以此类推

C语言基础总结

o #include <stdio.h>

o

o int main()

o {

o

o

o int n = 0;

o while (n <= 0) {

o printf("请输入一个整数\n"); o scanf("%d",&n); o }

o

o

o for (int i = n; i>0; i--) {

o for (int a = i; a > 0; a--) { o printf("*");

o }

o printf("\n");

o }

o

o return 0;

o }

o

? 输出九九乘法

o #include <stdio.h>

o

o int main()

o {

o int sum=0;

o for (int i = 1; i<10; i++) {

o for (int n = 1; n <= i; n++) {

o sum = i * n;

o printf("%dx%d=%d ",i,n,sum);

o }

o

C语言基础总结

printf("\n"); 表

o }

o

o return 0;

o }

七、break和continue

? break:

? 1.使用场合

o 1> switch语句:退出整个switch语句 o 2> 循环结构:退出整个循环语句 o * while

o * do while

o * for

? 2.注意点

o 只对最近的循环结构有效

? continue:

? 1.使用场合

o 循环结构:结束当前这次的循环体,进入下一次循环体 o * while

o * do while

o * for

? 2.注意点

o 只对最近的循环结构有效

作业

一、改错题 1.

? #include <stdio.h> ? 2015-2-27 21:45:00

?

?

?

?

?

?

?

?

?

?

2.

?

?

? int main() { int score; int age; scanf("%d %d\n", score, age); //“”内不能有\n,后面的变量前面要加上& printf("age是%d,score是%d\n", age, score); return 0; } #include <stdio.h> int main()

? {

? int a = 10++;//常量后面不能加++ ?

? int b = 10.0 % 2; %两边必须是整形 ?

?

3.

?

?

?

?

?

?

?

?

?

?

?

? return 0; } #include <stdio.h> int main() { int a = 10; switch (a) { case 0: int b = 20 + a; //定义了新的变量,需要加{}

? break; ? ? case 2: ?

? break; ? }

?

? return 0; ? }

二,分析题

1> 第一题

? int x = 2,y=3; ? switch(x) ? {

? case 2: ? y++; ? case 3: ? y+=2; ? case 4:

? y+=3;

? default:

? y = 0;

? break;

? }

? printf("y=%d\n", y);

o 0 因为没有break

2> 第二题

? int x = 1,y = 1;

? if(x++==2 && ++y==2) {

? x =7;

? }

? printf("x=%d, y=%d\n", x, y);

o x = 2 , y = 1 //因为首先x++是先赋值后计算,所以x++ == 2是不成立的,然后++y == 2 就不会判断 结果就是2 1

3> 第三题

? int x = 1,y = 1;

? if(x++==2 || ++y==2) {

? x =7;

? }

? printf("x=%d, y=%d\n", x, y);

o x=7,y=2 //因为||在判定完第一个条件之后,也会判定第二个条件,

所以,++y=2成立

三、编程题

题目:程序运行的时候提示下列信息

请输入相应数字选择需要执行的运算:

1 加法

2 减法

用户选择运算后,再提示用户输入两个需要进行运算的整数,输入完毕后就输出运算结果

? #include <stdio.h>

?

? int sum(int a, int b)

? {

? return a + b;

? }

?

? int minus(int a , int b)

? {

? return a - b;

? }

?

? int main()

? {

? printf("请选择所要进行的运算,加法请输入1,减法请输入2\n"); ?

? int num;

?

? scanf("%d",&num);

?

? int a ,b;

?

? printf("请输入要进行运算的两个值,以空格分开\n");

?

? scanf("%d %d",&a,&b);

?

? int result;

?

? switch (num) {

? case 1:

? result = sum(a,b);

? printf("结果为%d\n",result); ? break;

? case 2:

? result = minus(a,b);

? printf("结果为%d\n",result); ? break;

? default:

? printf("您输入的值不正确\n"); ? break;

? }

?

?

? return 0;

? }

函数

一、什么是函数 2015-2-27 21:45:00

? 任何一个C语言程序都是由一个或者多个程序段(小程序)构成的,每个程序段都有自己的功能,我们一般称这些程序段为“函数”。所以,你可以说C语言程序是由函数构成的。

? 比如你用C语言编写了一个MP3播放器程序,那么它的程序结构如下图所示:二、函数的定义

? 定义函数的目的

o 将一个常用的功能封装起来,方便以后调用

? 定义函数的步骤

o 函数名:函数叫什么名字

o 函数体:函数是干啥的,里面包含了什么代码

? 格式

o 固定格式(很多语言的函数都是这么写的)

o 返回值类型 函数名(形式参数列表)

o {

o 函数体

o }

三、函数调用

? sum(10, 11); 引出返回值

? 说明函数的调用过程

? 简述return的作用

o 1> 退出函数

o 2> 返回一个具体值给函数调用者

四、函数的参数

? 参数注意点

? 1.形式参数:定义函数时函数名后面中的参数,简称形参

? 2.实际参数:调用函数式传入的具体数据,简称实参

? 3.实参个数必须等于形参个数

? 4.函数体内部不能定义和形参一样的变量

? 5.如果是基本数据类型作为函数形参,纯粹是值传递,修改函数内部形参的值,并不会影响外面实参的值

? 6.一个函数可以没有形参,也可以有无限多个形参

五、函数的返回值

? 返回值的基本概念、return的作用

? void

? return

o void可以省略return

o 可以多次使用return

o return后面不能有其他语句

? 函数的弱语法

o 如果没有写返回值类型,默认是int o 如果写了返回值,可以不返回

o 调用一个没有定义过的函数

六、定义函数的步骤

1.明确函数作用,起一个有意义的函数名称

2.明确函数的参数和返回值

七、函数注意

? 1.默认情况下,不允许有函数的名称一样 ? 2.函数不能嵌套定义

? 3.函数不能重复定义,但是可以重复声明 ? 4.如果有函数的声明,没有函数的定义

o 1> 编译可以通过,因为编译器只会检测语法合不合理,并不会检测

函数有没有定义

o 2> 链接报错,因为链接的时候会检测函数是否定义

八、函数的补充

1.main函数

? 返回值:0,正常退出;1,异常退出

2.printf函数

? #include

? 返回值:字符串的长度

九、练习

? 编写一个函数double avr(int a, int b),计算a和b的平均值

o #include <stdio.h>

o

o double avr(int a, int b)

o {

o return (a+b)/2;

o }

o int main()

o {

o printf("请输入要求平均值的两个数\n");

o

o int a = 0,b = 0;

o

o scanf("%d %d",&a,&b);

o

o double c = avr(a,b);

o

o printf("平均值为%f\n",c);

o

o return 0;

o }

? 编写一个函数int pows(int base, int n)返回base的n次方

? 编写一个函数int pieAdd(int n),计算1+2+3+……+n的值并返回。比如pieAdd(3)的返回值是1+2+3=6

十、函数的声明

1.函数的定义顺序

? 1> 根据函数的作用,起一个有意义的名称

? 2> 确定函数的形参个数

? 3> 确定函数的返回值

2. 只有函数声明、没有定义,编译警告、链接报错

十一、.h文件和.c文件的分工

1.单文件的坏处

? 一个文件的内容太多,不利于阅读、调试

? 多人修改同一个文件出问题

? 公司里面是团队合作

2.将sum函数抽取到另一个.c文件中

? 先直接调用sum函数,编译警告、链接main.c错误

? #include “sum.c” , 编译链接main.c,运行成功(画图分析.o文件中的东西)

? 如果avr.c中使用sum.c,编译链接main.c,运行程序(画图分析出错原因)

3. 在其他文件中声明sum函数

? int sum(int,int);

? 编译链接main.c

? 编译链接sum.c

? 编译链接main.c sum.c,运行成功

? avr.c利用一样的方法

4. 将int sum(int,int)抽取到另外一个文件中

? 不抽取声明的坏处:增加新的函数了

? 抽取到.c文件中?开发工具会将所有的.c进行编译链接

? 抽取到.h文件中

5. 抽取步骤总结

? .c文件写函数的定义

? .h文件写函数的声明

? 要想用我的函数,请包含我的.h文件

? 好处分析

?

?

? 链接: 把项目中所有相关联的.o文件、C语言函数库合并在一起,生成可执行文件

?

?

6.使用多文件开发的步骤

? 1.函数的定义放.c文件,函数的声明放.h文件

? 2.如果要使用某个.c文件中定义的函数,只需要 #include这个.c文件对应的.h文件

? 3..h文件的作用:被别人拷贝。编译链接的时候不需要管.h文件 ? 4.cc xx.o xxx.o 将多个目标文件链接在一起

? cc xx.c xxx.c 将多个源文件编译、链接

十二、 #include

1.预处理指令简介

2.#include的作用

? 纯粹是文件拷贝

3.#include <stdio.h>

? stdio.h中有什么?链接的时候做了什么事情

? <>和””的区别

4.#include的路径问题

? 默认是同路径,其他问题以后再讨论

2015-2-27 21:45:00

进制和内存分析

一、进制

1.什么是进制

? 是一种计数的方式,数值的表示形式

2.二进制

? 特点:只有0和1,逢2进1

? 书写格式:0b或者0b开头

o 二进制 以0b 或者 0B开头

o 八进制 以0开头

o 十六进制 以0x或者0X开头 2015-2-27 21:45:00

? 使用场合:二进制指令\二进制文件,变量在内存中就是二进制存储 ? n为二进制位所能表示的数据范围(不考虑负数):0~2的n次方-1

3.八进制

? 特点:0~7,逢八进一

? 书写格式:0开头

4.十六进制

? 特点:0~F,逢十六进一

? 书写格式:0x或者0X开头

5.总结

1>mac中计算器的使用

2>printf以不同形式进行输出

6.习题

1> 判断下列数字是否合理

00011 0x0011 0x7H4 10.98 0986 .089 -109 +178 0b325 0b0010 0xFFdc 96f 96.0f 96.0F -.003 15.4e6 10e8.7 7.6e-6

2> 分别写出它们的十进制、八进制、十六进制

0b0011 1101 0b0111 1011

3> 写出它们的二进制

67 056 0x004f

二、变量的内存分析

研究变量在内存中的具体存储情况

1. 字节和地址

C语言基础总结

? 为了更好地理解变量在内存中的存储细节,先来认识一下内存中的“字节”和“地址”。

? 内存以“字节为单位”

2.变量的存储

? 所占用字节数跟类型有关,也跟编译器环境有关

?

? 变量实例

o int b = 10;

o int a = 134;

o 内存由大到小寻址

o 只存储二进制形式

o 每个变量都有地址:第一个字节的地址就是变量的地址

? 查看内存地址的两种方式:%x和%p

? 查看整数的二进制形式

o void putBinary(int n)

o {

o int bits = sizeof(n) * 8;

o while (bits-->0) {

o printf("%d", n>>bits&1); o if (bits%4==0) printf(" "); o }

o printf("\n");

o }

3.负数在内存中的存储

? 一个字节的取值范围

? 负数的表示形式

? 原码、反码、补码

4.取值范围

?

5.练习

? 写出下列变量在内存中的存储情况

o int a = 134;

o int b = 0;

o int c = -10;

三、类型说明符

1.short和long

? short和long可以提供不同长度的整型数,也就是可以改变整型数的取值范围。在64bit编译器环境下,int占用4个字节(32bit),取值范围是-231~231-1;short占用2个字节(16bit),取值范围是-215~215-1;long占用8个字节(64bit),取值范围是-263~263-1

? 总结一下:在64位编译器环境下,short占2个字节(16位),int占4个字节(32位),long占8个字节(64位)。因此,如果使用的整数不是很大的话,可以使用short代替int,这样的话,更节省内存开销。

? 世界上的编译器林林总总,不同编译器环境下,int、short、long的取值范围和占用的长度又是不一样的。比如在16bit编译器环境下,long只占用4个字节。不过幸运的是,ANSI \ ISO制定了以下规则:

o short跟int至少为16位(2字节)

o long至少为32位(4字节

C语言基础总结

)

o short的长度不能大于int,int的长度不能大于long

o char一定为为8位(1字节),毕竟char是我们编程能用的最小数据类型

? 可以连续使用2个long,也就是long long。一般来说,long long的范围是不小于long的,比如在32bit编译器环境下,long long占用8个字节,long占用4个字节。不过在64bit编译器环境下,long long跟long是一样的,都占用8个字节。

? 还有一点要明确的是:short int等价于short,long int等价于long,long long int等价于long long

2.signed和unsigned

? 首先要明确的:signed int等价于signed,unsigned int等价于unsigned ? signed和unsigned的区别就是它们的最高位是否要当做符号位,并不会像short和long那样改变数据的长度,即所占的字节数。

o signed:表示有符号,也就是说最高位要当做符号位,所以包括正数、负数和0。其实int的最高位本来就是符号位,已经包括了正负数和0了,因此signed和int是一样的,signed等价于signed int,也等价于int。signed的取值范围是-231 ~ 231 - 1

o unsigned:表示无符号,也就是说最高位并不当做符号位,所 以不包括负数。在64bit编译器环境下面,int占用4个字节(32bit),因此

unsigned的取值范围是:0000 0000 0000 0000 0000 0000 0000 0000 ~ 1111 1111 1111 1111 1111 1111 1111 1111,也就是0 ~ 232 - 1

四、位运算

1.&按位与

? 功能

o 只有对应的两个二进位均为1时,结果位才为1,否则为0。 ? 举例: 比如9&5,其实就是1001&101=1,因此9&5=1

? 规律

o 二进制中,与1相&就保持原位,与0相&就为0//说的不是与数字1相与,而是某一位上面的1

2.|按位或

? 功能

o 只要对应的二个二进位有一个为1时,结果位就为1,否则为0。 ? 举例: 比如9|5,其实就是1001|101=1101,因此9|5=13

3.^按位异或

? 功能

o 当对应的二进位相异(不相同)时,结果为1,否则为0。

? 2> 举例: 比如9^5,其实就是1001^101=1100,因此9^5=12

? 3> 规律

o 相同整数相^的结果是0。比如5^5=0

o 多个整数相^的结果跟顺序无关。比如5^6^7=5^7^6

o 因此得出结论:a^b^a = b

4.~取反

? 对整数a的各二进位进行取反,符号位也取反(0变1,1变0)

5.<< 左移

? 把整数a的各二进位全部左移n位,高位丢弃,低位补0。左移n位其实就是乘以2的n次方

? 由于左移是丢弃最高位,0补最低位,所以符号位也会被丢弃,左移出来的结果值可能会改变正负性

6.>> 右移

? 把整数a的各二进位全部右移n位,保持符号位不变。右移n位其实就是除以2的n次方

? 为正数时, 符号位为0,最高位补0

? 为负数时,符号位为1,最高位是补0或是补1 取决于编译系统的规定

7.习题

? 在不用引入其他变量的情况下,使用位异或^运算符实现两个变量值的互换 ? 使用位与&运算符变量的奇偶性

? 编写一个函数,用来输出整数在内存中的二进制形式

五、char类型

1.存储细节

? ASCII单字节表(双字节GBK\GB2312\GB18030\Unicode)

2.常见错误

? char c = A;

? char c = "A";

? char c = 'ABCD';

? char c = '男';

3.当做整型使用

? 在-128~127范围内,可以当做整数来用

4.%c和%d\%i的使用

? printf(“%d”, ‘A’);

? printf(“%c”, 68);

5.转义字符

? \n 回车

? \t tab

? \\ \

?

?

?

6.

?

? \' ' \" " \0 空字符,结束字符串 编写一个函数,将小写字母转为大写说出程序的输出结果

o int main()

o {

o int i = 67 + '4'; o char c = 'c' - 10; o

o printf("%d - %c\n", i, i); o printf("%d - %c\n", c, c); o return 0;

o }

数组与字符串

一、数组的基本概念 2015-2-27 21:45:00

一个int类型的变量能保存一个人的年龄,如果想保存整个班的年龄呢?

1.什么是数组

? 数组,从字面上看,就是一组数据的意思,没错,数组就是用来存储一组数据的

2.数组的特点

? 只能存放一种类型的数据,比如int类型的数组、float类型的数组 ? 里面存放的数据称为“元素”

二、数组的定义

1.定义

? 声明数组的类型

? 声明数组的元素个数(需要多少存储空间)

2.格式

? 元素类型 数组名[元素个数];

? 比如:int ages[3];

3.简单实用

? 简单初始化:int ages[5] = {19, 19, 20, 21, 25};

? 元素有顺序之分,每个元素都有一个唯一的下标(索引),从0开始 ? 数组元素的访问:a[i]

4.初始化

? 初始化方式

o int a[3] = {10, 9, 6};

o int a[3] = {10,9};//这种初始化方式没有定义的元素默认为0

o int a[] = {11, 7, 6};

o int a[4] = {[1]=11,[0] = 7};

? 常见错误

o int a[];

o int[4] a;

o int a[b];

o a = {10, 11};

o a[4] = {10,9,8,5};

5.内存分析

? 数组存储空间的大小

? 存储空间的划分(内存的分配是从高地址到低地址进行的,但一个数组内部元素又是从低到高进行的)

? 数组名的作用,查看元素地址

? 数组越界的注意

6.其他使用

? 数组与函数参数

o 数组元素作为函数参数

o 数组作为函数参数(sizeof注意)

? // 数组作为函数参数,可以省略元素个数

? // 数组作为函数参数,传递是整个数组的地址,修改函数形参

数组元素的值,会影响到外面的实参数组

? 遍历数组元素

o 两种方式遍历(while循环和for循环)

o 遍历元素值和元素地址

o 字符数组的使用

三、二维数组

1.什么是二维数组

? 一个数组能表示一个班人的年龄,如果想表示很多班呢?

? 什么是二维数组?int ages[3][10]; 三个班,每个班10个人

? 相当于3行10列

? 相当于装着3个一维数组

? 二维数组是一个特殊的一维数组:它的元素是一维数组。例如int a[2][3]可以看作由一维数组a[0]和一维数组a[1]组成,这两个一维数组都包含了3个int类型的元素

?

2.存储

? 存储大小

? 存储结构和顺序

? 存储地址问题

3.初始化

? int a[3][4] = {1,2,3,4,5,6}; ? int a[3][4] = {{},{},{}};

? 数组元素简单访问

? int a[][5] = {3,21,31,2,32,1}; ? 注意错误:

o int a[3][4];

o a[3] = {};

4.遍历

? 遍历所有的元素

? 遍历地址

? 使用场合:五子棋、俄罗斯方块

四、字符串

1.什么是字符串

? 简单的字符串”itcast”

? 一个’i’是一个字符

? 很多个字符组合在一起就是字符串了

2.字符串的初始化

? char a[] = “123”; 和 char a [] = {‘1’,’2’,’3’};的区别,可以比较大小 ? “123”其实是由’1’、’2’、’3’、’\0’组成

? “123”的存储分布

? 字符串的输出”%s”,’\0’是不会输出的

3.\0的作用

? 输出char a[] = {‘o’,’k’};

? 在char a[]前面搞个”mj”

? 输出”mj”

? 再输出a

? char a[] = {‘i’,’t’,’\0’,’c’};

4.常用字符串处理函数

? strlen与sizeof的区别

o strlen

? strlen函数:计算字符串长度

? 1.计算的是字符数,并不是字数。一个汉字算作3个字符

? 2.计算的字符不包括\0

? 3.从某个地址开始数字符的个数,直到遇到\0为止

o sizeof是指该变量在内存中的大小

? 举例:

? char ss[100] = "0123456789";

? sizeof(ss) 结果是100 ===》ss表示在内存中的大小

100×1

? strlen(ss) 结果是10 ===》strlen是个函数,内部实现

是用一个循环计算到\0之前为止

o strlen函数声明在string.h文件中

5.练习

? 编写一个函数char_contains(char str[],char c),如果字符串str中包含字符c则返回数值1,否则返回数值0

五、字符串数组

1.使用场合

? * 一维字符数组中存放一个字符串,比如一个名字char name[20] = "mj" ? * 如果要存储多个字符串,比如一个班所有学生的名字,则需要二维字符数

组,char names[15][20]可以存放15个学生的姓名(假设姓名不超过20字符) ? * 如果要存储两个班的学生姓名,那么可以用三维字符数组char names[2][15][20]

2.初始化

? char names[2][10] = { {'J','a','y','\0'}, {'J','i','m','\0'} };

? char names2[2][10] = { {"Jay"}, {"Jim"} };

? char names3[2][10] = { "Jay", "Jim" };

指针

一、指针前奏

1.指针的重要性 2015-2-27 21:45:00

? 指针是C语言中非常重要的数据类型,如果你说C语言中除了指针,其他你都学得很好,那你干脆说没学过C语言。

2.需求

? void change(int n)函数调用完毕后,改变实参的值

? 分析:修改实参的值->找到存储空间->地址

二、指针变量的定义

1.定义的格式

? 类名标识符 *指针变量名;

? int *p;

2.先定义后赋值

? 简单取值

o int a = 10;

o int *p;

o p = &a;

o printf(“%d”, *p);

? 简单改值

o *p = 9;

3.定义的同时赋值

? int a = 10; ? int *p = &a;

4.实现修改实参

?

? #include <stdio.h> ?

? void change(int *n); ?

? int main()

? {

? int a = 90; ?

? change(&a); ?

? printf("%d\n", a); ?

? return 0; ? }

?

? void change(int *n)

? {

? *n = 10;

? }

5.使用注意

? 不建议的写法, int *p只能指向int类型的数据

o int *p;

o double d = 10.0;

o p = &d;

? 指针变量只能存储地址

o int *p;

o p = 200;

? 指针变量未经过初始化,不要拿来间接访问其他存储空间

o int *p;

o printf("%d\n", *p);

? 定义变量时的*仅仅是一个象征,没有其他特殊含义 ? 这个时候的*的作用:访问指向变量p指向的存储空间

o *p = 20;

? %p输出指针里面存储的地址值

6.清空指针

? p = 0;

? p = NULL;

三、指针实例

1.void swap(char *a, char *b) (注意temp=a;

? #include <stdio.h>

?

? void swap(char *a, char *b);

?

? int main()

? {

? char a = 'A',b = 'B';

?

? swap(&a,&b);

?

? printf("%c %c\n", a,b);

?

? return 0; a = b; b = temp;)

? }

?

? void swap(char *a,char *b)

? {

? *a = *a - *b;

? *b = *a + *b;

? *a = *b - *a;

? }

2.int sumAndMinus(int a, int b, int *minus)

? #include <stdio.h>

?

? int sumAndMinus(int a, int b, int *minus); ?

? int main()

? {

? int a = 10;

? int b = 20;

? int minus;

?

? int sum = sumAndMinus(a,b,&minus); ?

? printf("和为%d,差为%d\n", sum,minus); ?

? return 0;

? }

?

? int sumAndMinus(int a, int b, int *minus) ? {

? *minus = a - b;

? return a + b;

? }

四、指针研究

1.指针变量所占用的存储空间

? 8个字节

2.为何指针变量要分类型?

? int i = 2;

? char c = 1;

? int *p = &c;

? printf(“%d”, *p);

五、指针与数组

1.指向一位数组元素的指针

2.用指针遍历一位数组元素

? 先遍历char数组(‘i’,’t’),再遍历int类型数组

? *(p+i)和*(p++)的区别

? a+i和a++

? p[0]、p[1]

3.习题

? 设计一个函数:int arraySum(int a[], int n),求一维数组a前n个数的和。现在利用int *p替换int a[]

o #include <stdio.h>

o

o int arraySum(int *p, int n);

o

o int main()

o {

o int a[]={1,2,3,4,5,6}; o

o int sum = arraySum(a,5); o

o printf("%d\n",sum); o

o return 0;

o }

o

o int arraySum(int *p, int n) o {

o int sum = 0;

o for (int i = 0; i<n; i++) o {

o sum = sum + *(p+i); o }

o return sum;

o }

六、指针与字符串

1.字符串回顾

? char s[] = “mj”;

2.其他定义字符串的方式

? char *s="mj";

? char *s; s = "mj";

3.两种定义方式的区别

? 内存分析

? 画图分析

? 常量和变量字符串的区别 ? 常量的内存地址查看

4.补充

? 1.常量区

? 存放一些常量字符串 ?

? 2.堆

? 对象

?

? 3.栈

? 存放局部变量

?

? 掌握:

? 定义字符串的2种方式

? 1> 利用数组

?

?

?

?

?

?

?

?

4.习题

? char name[] = "itcast"; * 特点:字符串里面的字符是可以修改的 * 使用场合:字符串的内容需要经常修改 2> 利用指针 char *name = "itcast"; * 特点:字符串其实是一个常量字符串,里面的字符是不能修改 * 使用场合:字符串的内容不需要修改,而且这个字符串经常使用编写一个int string_len(char *s),返回字符串s的字符长度

o #include <stdio.h>

o #include <string.h>

o int string_len(char *s);

o

o int main()

o {

o char a[] = "itcast123123123";

o

o int longth = string_len(a);

o

o printf("%d\n",longth);

o

o return 0;

o }

o

o int string_len(char *s)

o {

o return strlen(s);

o }

七、返回指针的函数

? 指针也是C语言中的一种数据类型,因此一个函数的返回值肯定可以是指针类型的

? 返回指针的函数的一般形式为:类型名 * 函数名(参数列表)

o 例:

o #include <stdio.h>

o char *test();

o

o /*

o 只要求能看懂

o */

o

o int main()

o {

o char *name = test(); o

o printf("name=%s\n", name); o

o return 0;

o }

o

o char *test()

o {

o return "rose";

o }

八、指向函数的指针

1.为什么指针可以指向一个函数

? 函数作为一段程序,在内存中也要占据部分存储空间,它也有一个起始地址,即函数的入口地址。函数有自己的地址,那就好办了,我们的指针变量就是用来存储地址的。因此,可以利用一个指针指向一个函数。其中,函数名就代表着函数的地址。

2.指向函数的指针的定义

? 定义的一般形式:函数的返回值类型 (*指针变量名)(形参1, 形参2, ...);

3.使用注意

? 由于这类指针变量存储的是一个函数的入口地址,所以对它们作加减运算(比如p++)是无意义的

? 指向函数的指针变量主要有两个用途:

o 调用函数

o 将函数作为参数在函数间传递

4.实际用法

? 掌握:

? 1.看懂语法

? 2.定义指向函数的指针

? double (*p)(double, char *, int); ? p = haha;

? 或者

? double (*p)(double, char *, int) = haha; ? 3.如何间接调用函数

? 1> p(10.7, "jack", 10);

? 2> (*p)(10.7, "jack", 10);

2015-2-27 21:45:00

C语言基础总结

? 算术运算符:用于各类数值运算。包括加(+)、减(-)、乘(*)、除(/)、求余(或称模运算,%)、自增(++)、自减(--)共七种。

? 关系运算符:用于比较运算。包括大于(>)、小于(<)、等于(= =)、大于等于(>=)、小于等于(<=)和不等于(!=)六种。

? 逻辑运算符:用于逻辑运算。包括与(&&)、或(||)、非(!)三种。

? 位操作运算符:参与运算的量,按二进制位进行运算。包括位与(&)、位或(|)、位非(~)、位异或(^)、左移(<<)、右移(>>)六种。

? 赋值运算符:用于赋值运算,分为简单赋值(=)、复合算术赋值(+=,-=,*=,/=,%=)和复合位运算赋值(&=,|=,^=,>>=,<<=)三类共十一种。

? 条件运算符:这是一个三目运算符,用于条件求值(?:)。

? 逗号运算符:用于把若干表达式组合成一个表达式(,)。

? 指针运算符:用于取内容(*)和取地址(&)二种运算。

求字节数运算符:用于计算数据类型所占的字节数(sizeof)。

? 特殊运算符:有括号(),下标[],成员(→,.)等几种。

常量都有哪些

? 整形

? 浮点型

? 字符型 总结

? 字符串

数据类型

? 基本数据类型

? 构造类型

? 指针类型

? 空类型

流程控制分哪几种

? 顺序结构

? 选择结构

? 循环结构

int x=017; 一定要弄清楚为什么是这个结果!过程很重要

? printf(“%d,” x); 15

? printf(“%o,” x); 17

? printf(“%#o,”x); 017

? printf(“%x,” x); 11

? printf(“%#x,”x); 0x11

printf中%5.1lf的含义

? 输出带符号的整数,需要占用5个字符位置, 不够则空格补齐. %5.1lf是右对齐,%-5.1lf是左对齐..1代表的是要留几位小数,如果输出的值为5.188那

么输出出来就会变成5.2.所以总体来说就是小数1位,总共5位,不够用空格补齐

? 如果是%10f那么情况就不一样了,本身float函数就要求保留6位小数,如果输出1.25,那么总共要10位,保留了6位小数之后,其他的右对齐,用空格补齐

变量类型、结构体、枚举

变量类型:

1.局部变量:

1> 定义:在函数(代码块)内部定义的变量(包括函数的形参)

2> 作用域:从定义变量的那一行开始,一直到代码块结束 2015-2-27 21:45:00

3> 生命周期:从定义变量的那一行开始分配存储空间,代码块结束后,就会被回收 4> 没有固定的初始值

2.全局变量

1> 定义:在函数外面定义的变量

2> 作用域:从定义变量的那一行开始,一直到文件结尾(能被后面的所有函数共享) 3> 生命周期:程序一启动就会分配存储空间,程序退出时才会被销毁 4> 默认的初始值就是0

3.练习

? #include <stdio.h>

?

? int a = 10;

?

? int b , c = 20;

?

? int sum(int v1, int v2) ? {

? return v1 + v2;

? }

?

? void test()

? {

? b++;

?

? int i = 0;

? i++;

?

? printf("b=%d, i=%d\n", b, i); ? }

?

? int main()

? {

? test();

? test();

? test();

?

? int e = 10;

?

? {

? {

? int f = 30;

? }

? }

?

? return 0;

? }

结构体:

1.数组与结构体的对比

? 数组:只能由多个相同类型的数据构成 ? 结构体:可以由多个不同类型的数据构成

2.结构体的定义

? // 1.定义结构体类型

? struct Person

? { // 里面的3个变量,可以称为是结构体的成员或者属性 ? int age; // 年龄

? double height; // 身高

? char *name; // 姓名

? }; // 别忘了结构体后面有分号

3.利用结构体类型,定义结构体变量

? // 2.根据结构体类型,定义结构体变量

? struct Person p = {20, 1.55, "jack"};

? p.age = 30;

? p.name = "rose";

? // 或者这种写法也是可以的

? struct Person p2 = {.height = 1.78, .name="jim", .age=30};

4.注意事项

? 错误写法

o struct Person p2;

o p2 = {30, 1.67, "jake"};

? 会将d1所有成员的值对应地赋值给d2的所有成员

o struct Date d1 = {2011, 4, 10};

o struct Date d2 = {2012, 8, 9};

o d2 = d1;

5.结构体内存分析

? 补齐算法

o 补齐算法(对齐算法)

o 结构体所占用的存储空间 必须是 最大成员字节数的倍数 ? 定义结构体时的内存分析

o 定义结构体类型(并不会分配存储空间)

o 定义结构体变量(真正分配存储空间)

6.定义结构体的三种方式

? 1.定义结构体变量的3种方式

o 1> 先定义类型,再定义变量(分开定义)

o struct Student

o {

o int age;

o };

o struct Student stu;

?

? 2> 定义类型的同时定义变量

o struct Student

o {

o int age;

o } stu;

o struct Student stu2;

?

? 3> 定义类型的同时定义变量(省略了类型名称)

o struct

o {

o int age;

o } stu;

?

7.结构体类型的作用域

? 定义在函数外面:全局有效(从定义类型的那行开始,一直到文件结尾) ? 定义在函数(代码块)内部:局部有效(从定义类型的那行开始,一直到代

码块结束)

8.结构体数组

? 例:

o int main()

o {

o struct RankRecord o {

o int no; // 序号 4 o int score; // 积分 4 o char *name; // 名称 8 o };

o

o

o

o

o

o

o

o

o

o struct RankRecord records[3] = { {1, "jack", 5000}, {2, "jim", 500}, {3, "jake",300} };

o return 0;

o }

? 注意:

o records[0].no = 4; / /不能写成records[0] = {4, "rose", 9000};

? 遍历:

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

o {

o printf("%d\t%s\t%d\n",

records[i].score);

o }

9.指向结构体的指针

? 1.指向结构体的指针的定义

o struct Student *p;

? 2.利用指针访问结构体的成员

o 1> (*p).成员名称

o 2> p->成员名称

? 访问结构体成员的几种方式

o // 第一种方式

o printf("age=%d, no=%d\n", stu.age, stu.no);

o

o // 第二种方式

o printf("age=%d, no=%d\n", (*p).age, (*p).no);

o

o // 第三种方式

o printf("age=%d, no=%d\n", p->age, p->no);

o

10.结构体与函数

? 如果结构体作为函数形参,只是将实参结构体所有成员的值对应地赋值给了形参结构体的所有成员。并且修改函数内部结构体的成员不会影响外面的实参结构体

? 相反,如果指向结构体的指针作为函数形参,那么更改函数内的成员参数,会修改函数外的结构体变量 records[i].no, records[i].name,

11.结构体的嵌套定义

? #include <stdio.h> ?

? int main() ? {

?

?

? struct Date { int year; ?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

枚举

1.概念 int month; int day; }; // 类型 struct Student { int no; // 学号 struct Date birthday; // 生日 struct Date ruxueDate; // 入学日期 // 这种写法是错误的 //struct Student stu; }; struct Student stu = {1, {2000, 9, 10}, {2012, 9, 10}}; printf("year=%d,month=%d,day=%d\n",stu.birthday.year, stu.birthday.month, stu.birthday.day); return 0; }

枚举是C语言中的一种基本数据类型,并不是构造类型,它可以用于声明一组常数。当一个变量有几个固定的可能取值时,可以将这个变量定义为枚举类型。

2.枚举的定义

? enum Season {spring, summer, autumn, winter};

3.枚举变量的定义

1>

? enum Season {spring, summer, autumn, winter};

? enum Season s;

2>

? enum Season {spring, summer, autumn, winter} s;

3>

? enum {spring, summer, autumn, winter} s;

4.枚举的使用注意

1>

? C语言编译器会将枚举元素(spring、summer等)作为整型常量处理,称为枚举常量。

2>

? 枚举元素的值取决于定义时各枚举元素排列的先后顺序。默认情况下,第一个枚举元素的值为0,第二个为1,依次顺序加1。

3>

? 也可以在定义枚举类型时改变枚举元素的值

? enum season {spring, summer=3, autumn, winter};

? 没有指定值的枚举元素,其值为前一元素加1。也就说spring的值为0,summer的值为3,autumn的值为4,winter的值为5

5.枚举的基本操作

1>赋值

? 可以给枚举变量赋枚举常量或者整型值

o enum Season {spring, summer, autumn, winter} s;

o s = spring; // 等价于 s = 0;

o s = 3; // 等价于 s = winter;

2. 遍历枚举元素

? enum Season {spring, summer, autumn, winter} s;

?

? // 遍历枚举元素

? for (s = spring; s <= winter; s++) { ? printf("枚举元素:%d \n", s); ? }

预处理指令 2015-2-27 21:45:00 预处理指令简介

? 1.C语言在对源程序进行编译之前,会先对一些特殊的预处理指令作解释(比如之前使用的#include文件包含指令),产生一个新的源程序(这个过程称为编译预处理),之后再进行通常的编译

? 2.为了区分预处理指令和一般的C语句,所有预处理指令都以符号"#"开头,并且结尾不用分号

? 3.预处理指令可以出现在程序的任何位置,它的作用范围是从它出现的位置到文件尾。习惯上我们尽可能将预处理指令写在源程序开头,这种情况下,它的作用范围就是整个源程序文件

? 4.C语言提供的预处理指令主要有:宏定义、文件包含、条件编译

一、不带参数的宏定义

1.一般形式

? #define 宏名 字符串

? #define ABC 10

? 右边的字符串也可以省略,比如#define ABC

2.作用

? 它的作用是在编译预处理时,将源程序中所有"宏名"替换成右边的"字符串",常用来定义常量。

3.使用习惯与注意

? 1> 宏名一般用大写字母,以便与变量名区别开来,但用小写也没有语法错误 ? 2> 对程序中用双引号扩起来的字符串内的字符,不进行宏的替换操作。 ? 3> 在编译预处理用字符串替换宏名时,不作语法检查,只是简单的字符串替换。只有在编译的时候才对已经展开宏名的源程序进行语法检查

? 4> 宏名的有效范围是从定义位置到文件结束。如果需要终止宏定义的作用域,可以用#undef命令

? 5> 定义一个宏时可以引用已经定义的宏名

o #define R 3.0

o #define PI 3.14

o #define L 2*PI*R

o #define S PI*R*R

二、带参数的宏定义

1.一般形式

? #define 宏名(参数列表) 字符串

? #define average(a, b) (a+b)/2

2.作用

? 在编译预处理时,将源程序中所有宏名替换成字符串,并且将 字符串中的参数 用 宏名右边参数列表 中的参数替换

o

o

o

o

o

o

o

o

o

o #include <stdio.h> #define average(a, b) (a+b)/2 int main () { int a = average(10, 4); printf("平均值:%d", a); return 0; }

3.使用注意

? 1> 宏名和参数列表之间不能有空格,否则空格后面的所有字符串都作为替换的字符串

o #define average (a, b) (a+b)/2

o 如果这样写,在替换average(10,4),会替换成(a,b) (a+b)/2(10,4); ? 2> 带参数的宏在展开时,只作简单的字符和参数的替换,不进行任何计算操作。所以在定义宏时,一般用一个小括号括住字符串的参数。所以在写带参数的宏的时候,最好都加上括号,每个变量加一个括号。

o #define D(a) 2*a

o int b = D(3+4);

o 这样会被替换为2*3+4,结果为10.

o 正确的写法应该是#define D(a) 2*(a)

? 3> 计算结果最好也用括号括起来

o #define Pow(a) (a) * (a)

o int b = Pow(10) / Pow(2);

o 这样接结果为10*10/2*2结果为100

o 应该写成#define Pow(a) ((a)*(a))

4.与函数的区别

? 从整个使用过程可以发现,带参数的宏定义,在源程序中出现的形式与函数很像。但是两者是有本质区别的:

o 1> 宏定义不涉及存储空间的分配、参数类型匹配、参数传递、返回值问题

o 2> 函数调用在程序运行时执行,而宏替换只在编译预处理阶段进行。所以带参数的宏比函数具有更高的执行效率

条件编译

1.概念

? 在很多情况下,我们希望程序的其中一部分代码只有在满足一定条件时才进

行编译,否则不参与编译(只有参与编译的代码最终才能被执行),这就是条件编译。

2.基本用法

? 1 #if 条件1

? 2 ...code1...

? 3 #elif 条件2

?

?

?

?

? 4 ...code2... 5 #else 6 ...code3... 7 #endif 1> 如果条件1成立,那么编译器就会把#if 与 #elif之间的code1代码编译进去(注意:是编译进去,不是执行,很平时用的if-else是不一样的) ? 2> 如果条件1不成立、条件2成立,那么编译器就会把#elif 与 #else之间的code2代码编译进去

? 3> 如果条件1、2都不成立,那么编译器就会把#else 与 #endif之间的code3编译进去

? 4> 注意,条件编译结束后,要在最后面加一个#endif,不然后果很严重(自己思考一下后果)

? 5> #if 和 #elif后面的条件一般是判断宏定义而不是判断变量,因为条件编译是在编译之前做的判断,宏定义也是编译之前定义的,而变量是在运行时才产生的、才有使用的意义

3.其他用法

? 1.#if defined()和#if !defined()的用法

o #if 和 #elif后面的条件不仅仅可以用来判断宏的值,还可以判断是否定义过某个宏。比如:

o 1 #if defined(MAX)

o 2 ...code...

o 3 #endif

o 如果前面已经定义过MAX这个宏,就将code编译进去。它不会管MAX的值是多少,只要定义过MAX,条件就成立。

o

o 条件也可以取反:

o 1 #if !defined(MAX)

o 2 ...code...

o 3 #endif

o 如果前面没有定义过MAX这个宏,就将code编译进去。

? 2.#ifdef和#ifndef的使用

o #ifdef的使用和#if defined()的用法基本一致

o #ifndef又和#if !defined()的用法基本一致

文件包含

1.基本概念

? 其实我们早就有接触文件包含这个指令了, 就是#include,它可以将一个文件的全部内容拷贝另一个文件中。

2.一般形式

? 1.第1种形式#include <文件名>

o 直接到C语言库函数头文件所在的目录中寻找文件

? 2.第2种形式 #include "文件名"

o 系统会先在源程序当前目录下寻找,若找不到,再到操作系统的path路径中查找,最后才到C语言库函数头文件所在目录中查找

3.使用注意

? 1.#include指令允许嵌套包含,比如a.h包含b.h,b.h包含c.h,但是不允许递归包含,比如 a.h 包含 b.h,b.h 包含 a.h。

? 2.使用#include指令可能导致多次包含同一个头文件,降低编译效率

o 为了解决这种重复包含同一个头文件的问题,一般我们会这样写头文件内容:

o

o

o

o

o

o #ifndef _ONE_H_ #define _ONE_H_ void one(); #endif

static与extern 2/27/2015 9:45:00 PM 对函数的作用

函数类型

? 外部函数:定义的函数能被本文件和其他文件访问。默认情况下,所有

函数都是外部函数

? 1>默认情况下所有函数都是外部函数

? 2>整个项目中不允许有同名外部函数

? 内部函数:定义的函数只能被本文件防伪,其他文件不能访问

? 1>但是内部函数不同文件里面可以同名

static 对函数的作用:

? 1> 定义一个内部函数

? 2> 声明一个内部函数

?

?

extern 对函数的作用:

? 1>完整地定义一个外部函数

? 2>完整地声明一个外部函数

? (extern可以省略,默认情况下声明和定义的函数都是外部函数) ?

对变量的作用

1.对全局变量的作用

1>全局变量分两种:

外部变量:定义的变量能被本文件和其他文件访问

1>默认情况下,所有的全局变量都是外部变量

2>不同文件中的同名外部变量,都代表着同一个变量,而且可以重复定义, 如果用得到,那就必须在其他文件中重复声明一下

内部变量:定义的变量只能被本文件访问,不能被其他文件访问。

1> 不同文件中的同名内部变量,互不影响

2>

? static 对变量的作用:

o 定义一个内部变量

? extern对变量的作用:

o 声明一个外部变量

? static 对函数的作用:

o 定义和声明一个内部函数

? extern 对函数的作用:

o 定义和声明一个外部函数(可以省略)

2.static对局部变量的作用

? static 修饰局部变量(改变生命周期,不改变作用域)

总结

?

?

?

? o 1> 延长局部变量的生命周期:程序结束的时候局部变量才会被销毁 o 2> 并没有改变局部变量的作用域 o 3> 所有的test函数都共享着一个static变量 o 4> static修饰局部变量的使用场合: o 如果某个函数的调用频率特别高 o 这个函数内部的某个变量值是固定不变的 1.extern可以用来声明一个全局变量,但是不能用来定义变量 2.默认情况下,一个全局变量是可以供多个源文件共享的,也就说,多个源文件中同名的全局变量都代表着同一个变量 3.如果在定义全局变量的时候加上static关键字,此时static的作用在于限制该全局变量的作用域,只能在定义该全局变量的文件中才能使用,跟其他源文件中的同名变量互不干扰 4.如果在定义局部变量的时候加上extern关键字,此时的作用在于改变这个变量的生命周期,这个变量的生命周期变为从定义的时候起,一直到整个程序结束。但是作用域不会变,定义在哪个函数里面还是只在哪个函数里面发生作用

typedef 2/27/2015 9:45:00 PM typedef 作用简介

? 我们可以使用typedef关键字为各种数据类型定义一个新名字(别名)。

typedef 与指针

? typedef char *MyP //这里面的MyP就是更改之后的名字,后面可以直接写 Myp p = "Jack";

typedef 与结构体

? typedef struct {

?

?

?

? int shengao; int tizhong; }Person; //这里面的Person就是结构体的名称,函数里可以写成Person p = {178,65}; ? 同时有两种写法

? 1.

o struct MyPoint {

o 3 float x;

o 4 float y;

o

o

o

o

? 2.

o

o

o

o

? 3.

o typedef struct {

o float x;

o float y;

o } Point;

typedef 与指向结构体的指针

? 4 typedef struct {

? 5 float x;

? 6 float y;

? 7 } Point; typedef struct MyPoint { float x; float y; } Point; 5 }; 6 7 // 起别名 8 typedef struct MyPoint Point;

? 8

? 9 // 起别名

? 10 typedef Point *PP;

?

typedef 与枚举类型

? typedef enum { sping,summer,spring,autumn}Season;

? 同时,枚举类型也有三种写法,参照结构体类型

typedef 与指向函数的指针

? 这个比较难,跟上面的写法完全不一样

o typedef int (*MyTest)(int,int);//这里面的MyTest就是新定义的

别名

o int test(int a,int b)

o

o

o

o

o { return a + b; } MyTest p = test;

o

typedef与#define

1.下面这两个的意思是一样的,最后都会被替换成为char *str = "This is a string";

? typedef char *String;

? String str = "This is a string!";

?

? #define String char *

? String str = "This is a string!";

2.但是下面的这两个就不一样了

? typedef char *String1;

? #define String2 char *

? String1 str1, str2;

? String2 str3, str4;

?

? 第三行这个是对的,可以运行,但是第四行就会报错

? String1 str1,str2; == char *str1;char *str2;

? String2 str1,str2; == char *str1,str2;//这样写是会报错的,因为指针只能一个一个定义,不能一起定义。如果这样定义,*将对str2不起作

用,导致str2编程一个char类型,结果为 char *str1;char str2;

更多类似范文
┣ c语言公共基础知识总结 8800字
┣ 二级C语言公共基础知识总结 700字
┣ 二级C语言公共基础知识总结 9000字
┣ C语言公共基础知识总结(不容错过) 2900字
┣ 更多c语言基础知识总结
┗ 搜索类似范文