*C语言的编程机制
C编程的基本策略是使用程序将源代码文件转为可执行文件,此文件包含可以运行的机器语言代码,C分成两步完成:编译和链接。
启动代码是程序和操作系统之间的接口。
库代码是C语言用到了标准C库中所包含的函数。
*C语言的基本元素关键字
关键字
也称保留字,它是C语言中具有特定含义,专门用做语言特定成分的标识符。
int, char, float ,struct ,sizeof,……
所有关键字都有固定的意义,不能用作其它功能。
*C语言的基本元素-标示符
标示符:标示符用来标识变量名,符号常量名,函数名,数组名,类型名,文件名的有效字符序列。
标示符组成规则:(不能使用关键字)
以字母(大小写均可)或以下划线开头
随后可以跟若干个(包括0个)字母,数字,下划线
标示符的长度各系统要求不同
C语言的基本元素-数据类型
整数类型
*C语言的基本元素-常量
在程序运行过程中,其值保值不变的量叫常量
按所属数据类型分为4种常量:
--整型常量
--实型常量
--字符型常量
--字符串常量
整型常量
三种形式:
十进制整数:由数字0~9和正负号表示。如123,-456,0
八进制整数:由数字0开头,后跟数字0~7表示。如0123,011
十六进制整数:由0x开头,后跟0~9,a~f表示。如0x123,0xff
实型常量,也称浮点数
表示形式(2种)
十进制数形式:(必须有小数点)如0.123,.123,123.0
指数形式:(e或E之前必须有数字,指数必须为整数)如12.3e3,123E2,1.23e4.
错误写法:e-5,1.2E-3.5,e3。
实型常量的类型
默认为double型
在实型常量后加字母f或F,默认它是float型,如12.3f
实型常量(浮点数)使用注意事项
int i = 0;
if(0 == i){print(“ok”);}//整形比较大小
浮点数数如何比较大小?
if(( f-2.6)>-1e-6 && ( f-2.6) <1e-6) { printf("OK"); }
//这里用if(f == 2.6f)是不合理的!
字符常量
定义:用单引号括起来的单个普通字符或转义字符
如‘a’ ‘A’ ‘?’ ‘\n’ ‘\101’
转义字符,表示特殊的动作,不能在屏幕上显示,反斜线后面跟一个字符或一个代码值表示
字符常量的值:一个字符其实是用一个8为整数表示的,故可以表示256种字符,表示字符的整数就是ASCII码。
如 ‘A’ - 65 ‘a’ - 97 ‘0’ - 48 ‘\n’ - 10
附:常见转义字符
\n---回车换行
\a---警报
\b---退格
\r---回车不换行,当前位置移到本行行首
\\---反斜杠
\’---单引号
\”---双引号
\ddd ---八进制值(d表示一个八进制数字)
如\101 表示10进制的65
\xhh ---十六进制值(h表示一个十六进制数字)
如\x41表示10进制的65
上面两个当我们想打印ASCII码对应的字符时可用。
字符串常量
定义:用双引号括起来的字符序列
存储:每个字符串尾会自动加一个‘\0’,作为字符串结束标志。
例如:字符串“hello”在内存中
h e l l o \0 字符串常量使用注意:
用空格隔开的连续的字符串被视为一个串。
除了按照所属数据类型,常量分为四种,从表现形式上看常量有下面几种形式:
1.字面常量 -1,3,4, .... 'a','b', "hello"
2.宏常量 #define Price 30
3.const常量 const int price=30;
4.每句常量 使用enum关键字
使用宏常量的好处:
1.增加程序可读性。
2.减少书写错误。
3.便于维护。
宏常量举例
#define PRICE 30
void main( )
{
int num, total;
num=10;
total=num * PRICE;
printf("total=%d",total);
}
使用const而不是宏来定义常量的好处:
1.const定义的常量编译器可以对其进行数据类型安全检查,而#define宏定义的常量却只能进行简单的字符替换,而且有时还会产生边际效应(不如你愿)
所谓边界效应举例如下:
#define N 100
#define M 200 + N
当程序中使用 M*N时, 原本想要 100* (200 + N)的 却变成了 100*200 +N
2.有些挑食程序可对const进行调试,但不对#define进行调试。
3.当定义局部常量是,const作用域仅限于定义局部变量的函数体内。但用#define时其作用域不仅限于定义局部常量的函数体内,而是从定义点到整个程序的结束点。
使用枚举常量
注:枚举常量一定是整型量,枚举常量不能取地址
枚举常量举例
int main( )
{
enum solution {a,b,c,d};//枚举常量
enum solution item= b;
printf("%d",item);
}
C语言的基本元素-变量
变量:在程序运行过程中,其值可以改变的量叫变量。
变量在内存中占一定的存储空间,在存储空间中存放的变量的值。
C语言中变量在使用前一定要先定义,再使用。且C语言中所有的变量定义要放在第一条可执行语句的前面。
变量定义的一般格式:
数据类型 变量1,变量2,…,变量n;
int a = 10;//定义的同时初始化
int a;//定义未初始化
a = 10;//赋值
变量的初值问题:
#include <stdio.h>
int i;
void main( )
{
static int j;
int k;
printf("%d,%d,%d.\n",i,j, k);
}
当变量定义没进行初始化时,
全局变量、静态变量系统默认分配初值,
局部变量系统不会分配初值。
变量运算中的隐式类型转换
什么情况下发生?
float f = 1.0;int* p = malloc(sizeof(int));
变量运算中的强制类型转换--显示转换
一般形式:(类型名)(表达式)
例: (int)(x+y)
(int)x+y
(double)(3/2)
(int)3.6
说明:强制转换得到所需类型的中间变量,原变量类型不变。
void main( )
{
float x = 3.6f;
int i;
i = (int)x;
printf("x = %f, i = %d", x, i);
}
变量声明:告诉编译器变量的类型、存储类型,不分配存储空间。
extern int i;
变量定义:告诉编译器在此处分配存储空间创建变量。
int i=1;
同一变量定义只能一次,但是可以声明多次。
*C语言的基本元素-结构体
结构体的引入-对基本数据类型的扩充
我们要编写一个处理学生数据的程序,这些数据有:
int num;
char name[20];
char sex;
int age;
float aver_score;
char addr[30];
结构体的引入
struct student
{
int num;
char name[20];
char sex;
int age;
float aver_score;
char addr[30];
};
结构体概念:多个的数据组合成的一个整体,它是一种构造数据类型。
结构体类型与结构体变量是不同概念。类型:不分配内存,不可参与运算。
结构体变量:分配内存,可以参与运算
结构体类型变量的定义-两种
第一种:先定义结构体类型,再定义结构体类型的变量。
例:
struct student
{
intnum;
char name[20];
char sex;
intage;
float score;
char addr[30];
};
struct student stu1, stu2;
第二种. 定义结构体类型的同时定义结构体变量,例:
struct student
{
int num;
char name[20];
char sex;
intage;
float score;
char addr[30];
} stu1, stu2;
对于无名结构体,只能采用第二种方法:
struct
{
int num;
char name[20];
char sex;
int age;
float score;
char addr[30];
} stu1, stu2;
对应结构体变量的定义方式,结构体变量的初始化方式也有两种:
1. 先定义结构体类型,再定义结构体类型的变量,在定义时初始化。
例 :
struct student
{ int num;
char name[20];
charsex;
int age;
char addr[30];
};
struct student stu1={112,“Wang Lin”,‘M’,19, “200 BeijingRoad”};
2. 定义结构体类型的同时定义结构体变量,同时初始化。
例:
struct student
{ intnum;
char name[20];
char sex;
int age;
char addr[30];
}stu1={112,“Wang Lin”,‘M’,19, “200Beijing Road”};
注意:同样的对于无名结构体只能采用这种方式初始化。
千万不可以这样“初始化”:
struct student
{
int num;
char name[20];
char sex;
int age;
char addr[30];
};
struct student stu1 ;
stu1 ={112,"WangLin",'M',19, "200 Beijing Road"};
//结构体不能整体赋值,可以定义的同时整体初始化
结构体变量访问方式:
1. 结构体变量名.成员名
2. 指向结构体变量的指针->成员名
3. (*指向结构体变量的指针).成员名例 struct student
{ int num;
char name[20];
charsex;
int age;
char addr[30];
};
struct student stu1;
struct student * pstu1 = &stu1;
pstu1->sex = ‘M’;//第二种
(*pstu1).sex = ’M’;//第三种
stu1.sex=’M’;//第一种
结构体嵌套时的成员使用
struct date
{ int month;
int day;
int year;
};
struct student
{ int num;
char name[20];
struct datebirthday;
}stu1,stu2;
stu1.birthday.day = 20;
对结构体变量的深入探讨
特点:
可以对结构体变量整体初始化;
可以将一个结构体变量整体赋值给另一个结构体变量。
可以对整个结构体变量或各成员取地址;
不可以在定义结构体类型时让成员带有初值。
不可以判断两个结构体变量是否相等;
#include <stdio.h>
#include <stdlib.h>
struct A
{
int i;
int j;
};
void main()
{
struct A a = { 1, 2 };
struct A b = a;
printf ( “%d,%d\n”, b.i, b.j );
if (a == b)
printf ("OK!\n");
}
*C语言的基本元素-枚举
枚举类型定义:
enum 枚举名 { 枚举元素表};
枚举变量定义,和结构体类似:
方法一:先定义枚举类型,再定义枚举变量
enum weekday{ sun,mou,tue,wed,thu,fri,sat };
enum weekday a,b,c;
方法二:定义枚举类型同时定义枚举变量
enum weekday{ sun,mou,tue,wed,thu,fri,sat }a,b,c;
都没有赋值 是从0开始允许多个枚举成员有相同的值.
没有显示赋值的枚举成员的值,总是前一个枚举成员的值+1.
*C语言的基本元素-共用体
共用体类型定义:
union 共用体名{
各成员
};
共用体变量定义与结构体变量定义类似。
共用体与结构体不同之处在于:
共用体变量中各成员项共同使用同一存储空间
一个共用体变量所占内存单元数为其成员中占用内存单元最长者的长度。
union p
{
short s;
char c[2];
double d;
}x;
*C语言的基础元素-运算符与表达式
基本算术运算符: + 、-、 *、 /、 %
使用注意:
自增、自减运算符使用注意:
1).++,--的操作对象只能是变量,如:++i; i++;
2).++, --比”*”优先级高,如*p++,等同于*(p++);
3).++i与 i++有差别
如:
j=3; k=++j;
j=3; k=j++;
指针变量与0值比较(指针非空比较)
尽管NULL的值与0相同,但是两者意义不同。假设指针变量的名字为p,它与零值比较的if语句如下:
if (NULL == p) 或
if (p != NULL) // p与NULL显式比较,强调p是指针变量
不要写成:
if (p == 0)
if (p != 0) // 容易让人误解p是整型变量
逻辑表达式 (注意“短路求值”一方面可以提高效率,另一方面有些语句没有走到)
a&&(b=1)
注意:对于&&如果a为假(0)则不再计算b,b=1也不会执行
a||(b=1)
注意:对于||如果a为真(1)则不再计算b,b=1也不会执行
条件表达式也是如此
(a > b )? ( c = a ) : b;
// a<=b的时候c=a不会被执行
*C语言的基本元素-语句
C语言以分号作分隔符,语句结束的标志。
编译后产生机器指令,完成一定操作任务。
1、简单表达式语句
如:i=1;x=sin(y);
如:printf(“Thisis a c program”);
如: ;
2、复合语句
将几个表达式组合在一起,形成一个复合表达式语句。
++i,++j;
i=1,j=2;
{
z =x+y;
t = z/100;
printf( “%f”, t );
}
*C语言的基本元素-程序结构
结构化程序设计由三种基本结构组成:
顺序结构
选择结构
循环结构
顺序结构:程序中的语句是从前到后依次执行的。它是最简单的一种基本结构。
先执行A操作,再执行B操作。
C语言中,选择结构用下面语句来实现。
if else 实例:
#include<stdio.h>
int main()
{
char c;
printf("input a character:");
c = getchar();
if(c < 32)
printf("This is a control character\n");
else if(c>='0'&&c<='9')
printf("This is a digit\n");
else
printf("This is an other character\n");
return 0;
}
switch, case流程图
swtich, case 实例:
#include<stdio.h>
int main()
{
int a;
printf(" input integernumber:");
scanf("%d",&a);
{
case 1:printf(“Monday”);break;
case 2:printf("Tuesday"); break;
case 3:printf("Wednesday"); break;
case 4:printf("Thursday"); break;
case 5:printf("Friday"); break;
case 6:printf("Saturday"); break;
case 7:printf("Sunday"); break;
default:printf("error");
}
return 0;
}
循环结构
为真时循环;
为真时循环;
为真时循环,但是无论是否为条件为真,
至少执行一次;
continue
与循环结构结合使用,中止当次循环,重新判断是否进行下次循环;
break
break使用在switch中,break可以跳出外层(仅一层)的switch结构;break使用在循环结构(for,while, do while)中, break可以跳出外层(仅一层)的循环结构。
break(红色)、continue(蓝色)在循环结构中的跳转
*C语言的基本元素-typedef
功能:用自定义名字为已有数据类型命名。
类型定义一般形式: typedef 原有类型 新别名;
例如:
typedef int INTEGER;
typedef float REAL;
INTEGER a,b,c;
REAL f1,f2;
说明:
1.typedef 没有创造新数据类型。
2. typedef 是定义类型别名,不能定义变量。
3. typedef 与 define 不同。
define 预处理时处理,简单字符置换。
typedef 编译时处理,为已有类型命名 。
#define PINT int *
PINT p1,p2;
typedef int * PINT;
PINT p1,p2;
用处:1 、用于屏蔽原始类型,变成通用形式:
typedef int INT16;
typedef unsigned char INT8U;
对于大型的软件开发,自己定义数据类型, 目的是增加系统的移植性。
2、用于重定义struct,union等类型(简化了代码)
typedef struct student
{ int num;
int age;
} STU;
STU stu1; // struct student stu1;
千万不要觉得typedef一次只能定义一个类型别名!
typedef struct student
{
int i;
char name[10];
}STU,*pSTU;
这种技巧在系统头文件中常被使用!