1、标识符
在C语言中,符号常量,变量,数组,函数等都需要一定的名称,我们把这种名称成为标识符
标识符划分:关键字,预定义标识符和用户标识符
2、标识符命名原则
命名规则:
1、只能由字母、数字、下划线或者美元符号($)组成
2、不能以数字开头D3、不能与关键字重名4、严格区分大小写
3、一般不能包括中文字体
3、C语言中的注释:
注释的内容就是在程序进行编译时,让编译器无视掉注释的内容。作用是用来方便程
序员阅读源代码的功能,说明某段代码的意思,或者做其他笔记
C语言有两种注释:
功能://符号右边的一行内容被编译器忽略(按了回车才算换行)
快捷键:Command + /(对应window键盘中的window键)
1、单行注释://注释的内容
功能:/* */符号里面的所有内容都被编译器忽略
2、多行注释:/* 注释的内容 */
4.C语言中字符和位数。
ch = getchar( ) 这表示的是从键盘上输入一个字符,不需要再按enter键。当然也可以用scanf 函数,,,字符的话要用%C。
字符可以做加减,这就相当于他们的as码值做加减,然后输出,对应的字符。
还有关于对齐的问题:
用一个浮点数的例子在说明
printf("%.2f\n"); 这个是一个浮点数保留2位小数
printf("%8f%8f\n"); 这个就是表示2个浮点数都占8位,并且是右对齐,当然在8前面加一个负号就是左对齐了,需要注意的不能写成这样:printf("%8f %8f\n"); 中间不能加空格,不然就会多一行
printf("%8.2f%8.2f\n"); 这个表示的是为每个数占8位,并且保留2位小数,这个也是右对齐。
第三章.分支结构
一. 一个语句中可以只有if,这样的话,如果成立则执行下面的内容否则直接把if语句跳过。
C语言中控制分支结构的主要是if语句和switch语句。首先说说if语句:
if语句的单分支结构形式:if(条件 e) { 语句 s; }。当条件e满足时,则执行花括号中的语句s。注(当花括号中只是单语句,即只有一条语句时,花括号可以省略,当然也可以不省略)。但如果是多个语录必须加花括号,不然运行结果不对,这时编译器是检测不出来的。
if语句的双分支结构形式:if(条件 e) { 语句 s1; } else { 语句s2; } 。当条件e满足时,则执行语句s1,当条件不满足时则执行else分支下的语句s2;
if语句的多分支结构形式:if(条件 1) { 语句 1; } elseif(条件 2) { 语句 2; } elseif(条件 3) { 语句 3; } ……elseif(条件 n) { 语句 n; } else { 语句 n+1; }
这里的多分支条件语句的含义是:如果条件1成立,则执行语句1;否则,如果条件2成立,则执行语句2;…… 否则,如果条件n成立,则执行语句n,
否则,如果前面的条件都不成立,则执行 else 分支下的语句n+1;
if还有嵌套结构
第七章:字符数组与字符串
字符转义序列:
转义字\ b \ f \ n \ r \ v \ t都是常用的输出设备控制字符
换页符\ f:把活跃位置移到下一页的开始处
换行符\ n:把活跃位置移动下一行的开始处
回车符\ r:把活跃位置移到当前行的开始处
水平制表符\ t:把活跃位置移到下一个水平制表点(一般是第1,9,17,25等位置处)
垂直制表符\ v:把活跃位置移到下一个垂直制表点
退格符\b:向后退一个活跃位置
数字转义序列:
1. 八进制转义字符(被看作是一个八进制整数,且是有符号整数(-128~127)(补码存储)!!若超过8位如\601('\201'打印整数为-127),要么发生截断要么编译错误!!跟编译器有关)
它是由反斜杠'\'和随后的1~3个八进制数字构成的字符序列。例如,'\60'、'\101'、'\141'分别表示字符'0'、'A'和'a'。因为字符'0'、'A'和'a'的ASCII码的八进制值分别为60、101和141。
字符集中的所有字符都可以用八进制转义字符表示。如果你愿意,可以在八进制数字前面加上一个0来表示八进制转移字符。
2. 十六进制转义字符
它是由反斜杠'\'和字母x(或X)及随后的1~2个十六进制数字构成的字符序列。例如,'\x30'、'\x41'、'\X61'分别表示字符'0'、'A'和'a'。因为字符'0'、'A'和'a'的ASCII码的十六进制值分别为0x30、0x41和0x61。
C语言中:
1 用scanf进行输入
int main( )
{char a[100];
scanf("%s",&a);
printf("%s\n",a);
return 0;
}
//用scanf进行输入,在输入时遇到空格' ',就会认为输入结束。所以用scanf输入的数据中不能有空白字符。
2 用gets进行输入
int main( )
{char a[100];
gets(a);
puts(a);
return 0;
}
与scanf不用的是,用gets进行输入时,遇到空格符不会结束,知道遇到回车符结束。a可以为字符串数组名也可以为字符串指针。
区别与联系:
gets(s)函数与 scanf("%s",&s) 相似,但不完全相同,使用scanf("%s",&s) 函数输入字符串时存在一个问题,就是如果输入了空格会认为字符串结束,空格后的字符将作为下一个输入项处理,但gets()函数将接收输入的整个字符串直到遇到换行为止。
1.scanf()
所在头文件:stdio.h
语法:scanf("格式控制字符串",变量地址列表);
接受字符串时:scanf("%s",字符数组名或指针);
2.gets()
所在头文件:stdio.h
语法:gets(字符数组名或指针);
两者在接受字符串时:
1.不同点:
scanf不能接受空格、制表符Tab、回车等;
而gets能够接受空格、制表符Tab和回车等;
2.相同点:
字符串接受结束后自动加'\0'。
stdio.h中的字符串函数:
sscanf函数
函数原型
int sscanf(const char *s,const char *format,..);
int scanf(const char *format,...);
sscanf与scanf类似,都是用于输入的,只是后者以键盘(stdin)为输入源,前者以固定字符串为输入源。
参数列表
buffer存储的数据
format格式控制字符串
argument 选择性设定字符串
返回值
成功则返回参数数目,失败则返回-1,错误原因存于errno中。
操作
1 * 亦可用于格式中, (即 %*d 和 %*s) 加了星号 (*) 表示跳过此数据不读入. (也就是不把此数据读入参数中)
2 {a|b|c}表示a,b,c中选一,[d],表示可以有d也可以没有d。
3 width表示读取宽度。
4 {h | l | I64 | L}:参数的size,通常h表示单字节size,I表示2字节 size,L表示4字节size(double例外),l64表示8字节size。
5 type :这就很多了,就是%s,%d之类。
6 特别的:%*[width] [{h | l | I64 | L}]type 表示满足该条件的被过滤掉,不会向目标参数中写入值。失败返回0 ,否则返回格式化的参数个数
7 支持集合操作
%[a-z] 表示匹配a到z中任意字符,贪婪性(尽可能多的匹配)
%[aB'] 匹配a、B、'中一员,贪婪性
%[^a] 匹配非a的任意字符,并且停止读入,贪婪性
使用实例
1 %*d,%*s:*号表示此数据不读入,忽略掉。
ch="MemTotal: 2028248 kB"
sscanf(ch,"%*s%d",&total);
printf("%d\n",total);
输出结果:2028248
2 取指定长度的字符串,,不带数字的,代表整体赋值。
sscanf("123456 ", "%4s", buf);
printf("%s\n", buf);
输出结果:1234
3 取到指定字符为止的字符串。如在下例中,取遇到空格为止字符串。
sscanf("123456 abcdedf", "%[^ ]", buf);
printf("%s\n", buf);
结果为:123456
4 sscanf(ch,"%*[^e]%[^2]",ch1);
寻找e到2之间的数,包括e但不包括2
如果中间有空格,包括空格。
5 给定一个字符串““hello, world”,仅保留world。(注意:“,”之后有一空格)
sscanf(“hello, world”, "%*s%s", buf);
printf("%s\n", buf);
结果为:world
%*s表示第一个匹配到的%s被过滤掉,即hello被过滤了
如果没有空格则结果为NULL。
6 分割字符串
sscanf("2006:03:18", "%d:%d:%d", a, b, c);
sscanf("2006:03:18 - 2006:04:18", "%s - %s", sztime1, sztime2);
如果2006:03:18 - 2006:04:18间没有空格
sscanf("2006:03:18 - 2006:04:18", "%[0-9,:] - %[0-9,:]", sztime1, sztime2);
sprintf
函数原型
int sprintf( char *buffer, const char *format, [ argument] … );
extern int printf(const char *format,...);
函数printf根据指定的格式将参数输出到屏幕上;
函数sprintf根据指定的格式将参数输出到由指针buffer指定的字符数组(字符缓冲区)中;
参数列表
buffer:char型指针,指向将要写入的字符串的缓冲区。
format:格式化字符串。
[argument]...:可选参数,可以是任何类型的数据。
返回值
返回写入buffer 的字符数,出错则返回-1. 如果 buffer 或 format 是空指针,且不出错而继续,函数将返回-1,并且 errno 会被设置为 EINVAL。
sprintf 返回被写入buffer 的字节数,结束字符‘\0’不计入内。即,如果“Hello”被写入空间足够大的buffer后,函数sprintf 返回5。
格式符
sprintf格式的规格如下所示。[]中的部分是可选的。
%[指定参数][标识符][宽度][.精度]指示符
若想输出'%'本身时, 请使用'%%'处理。
1. 处理字符方向。负号时表示从后向前处理。
2. 填空字元。 0 的话表示空格填 0;空格是内定值,表示空格就放着。
3. 字符总宽度。为最小宽度。
4. 精确度。指在小数点后的浮点数位数。
使用实例
1 把整数123 打印成一个字符串保存在s 中。
sprintf(s, "%d", 123); //产生"123"
2 按16进制以小写符号输出最小为8位的字符串
sprintf(s, "%08X", 4567); //产生:"000011D7"
3 char a1[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
char a2[] = {'H', 'I', 'J', 'K', 'L', 'M', 'N'};
sprintf(s, "%.7s%.7s", a1, a2);//产生:"ABCDEFGHIJKLMN"
这可以类比打印浮点数的”%m.nf”,在”%m.ns”中,m 表示占用宽度(字符串长度不足时补空格,超出了则按照实际宽度打印),n 才表示从相应的字符串中最多取用的字符数。通常在打印字符串时m 没什么大用,还是点号后面的n 用的多。自然,也可以前后都只取部分字符:
sprintf(s, "%.6s%.5s", a1, a2);//产生:"ABCDEFHIJKL"
sprintf(s, "%.*s%.*s", 7, a1, 7, a2);
或者:
sprintf(s, "%.*s%.*s", sizeof(a1), a1, sizeof(a2), a2);
4 实际上,前面介绍的打印字符、整数、浮点数等都可以动态指定那些常量值,比如:
sprintf(s, "%-*d", 4, 'A'); //产生"65 "
sprintf(s, "%#0*X", 8, 128); //产生"0X000080","#"产生0X
sprintf(s, "%*.*f", 10, 2, 3.1415926); //产生" 3.14"
5 sprintf(s, "%p", &i);//这里的P代表的地址,在printf中,如果是打印地址,也要用@。
6 strlen 便已经知道了结果字符串的长度。如:
int len = sprintf(s, "%d", i);
对于正整数来说,len 便等于整数i 的10 进制位数。
常用的字符串处理函数
C语言编译系统中提供了很多有关字符串处理的库函数,这些库函数为字符串处理提供了方便,下面总结下几种有关字符串处理的函数。
一、输出字符串函数puts:
格式:puts(字符数组名) ;
功能:puts函数用于输出一个以"\0"结尾的字符串,在输出时将"\0"转换为"\n",且输出的字符串中可以包含转义字符。
使用puts函数输出字符串时,需要使用#include命令将"stdio.h"头文件包含到源文件中。
二、输入字符串函数gets:
格式:gets(字符数组名);
功能:gets函数用于将输入的字符串内容存放到指定的字符数组中。
使用gets函数输入字符串时,需要使用#include命令将"stdio.h"头文件包含到源文件中。
在使用gets函数和puts函数时只能输入或输出一个字符串,不能写成puts(str1,str2)或gets(str1,str2)
三、字符串复制函数strcpy:
格式:strcpy(字符数组名,字符串名);
strcpy(字符数组名1,字符数组名2);
功能:将字符串内容复制到字符数组中。
注意:若将字符串或字符数组2前面的若干个字符复制到字符数组1中,则应用strncpy函数,其格式为:strncpy(字符数组,字符串,字符个数);或strncpy(字符数组1,字符数组2,字符个数);
static char str2[]=["How are you?"];
char str1[20];
strncpy(str1,str2,3);
.....
....
char str[20];
strncpy(str,"computer",3);
....
四、字符串比较函数strcmp:
格式:strcmp(字符串名1,字符串名2);
功能:将两个字符串的对应字符自左至右逐个进行比较(按照ASCII码值的大小),直到出现不同字符或遇到“\0”字符为止。比较结果由函数值带回。
说明:1、字符数组1必须足够长,以便容纳字符数组2中的全部内容,即:
static char str1[20]="Happy ";
static char str2[10]="New Year!";
strcat(str1,str2);
2、在连接前两个字符串后面都有一个'\0',连接时将字符数组1后面的"\0"去掉,只在新字符串后面保留一个"\0";
3、使用strcat函数连接两个字符串时,应使用#include命令将"string.h"头文件包含到源文件中;
4、strcat函数的返回值是字符数组1的地址。
五、字符串连接函数strcat:
格式:strcat(字符数组名1,字符数组名2);
功能:将字符数组2的内容连接到字符数组1 的后面,并在最后加一个“\0”,且将结果存放在字符数组1中。
注意:1、字符数组必须足够长,以便容纳字符数组2中的全部内容;
2、 连接前两个字符串后面都有一个'\0',连接时将字符数组1后面的“\0”去掉,只在新字符串后面保留一个“\0”;
3、使用strcat函数连接两个字符串时,应使用#include命令将“string.h”头文件包含到源文件中;
4、strcat函数的返回值是字符数组1的地址。
.....
char str1[20]={"This is a"};
char str2[]={"string."};
printf("%s",strcat(str1,str2));
....
程序运行结果:
This is a stirng.
也可用下面语句代替:
....
strcat(str1,str2);
printf("%s",str1);
六:测试字符串长度函数strlen:
格式:strlen(字符数组);
strlen(字符串);
功能:测试字符数组中字符串的长度。
1、函数值不包括'\0'在内的字符数组中支付差U了的实际长度值;
2、还可以直接对字符串的长度。
strchr
函数名: strchr
功 能: 在一个串中查找给定字符的第一个匹配之处\
用 法: char *strchr(char *str, char c);
程序例:
#include <string.h>
#include <stdio.h>
int main(void)
{
char string[15];
char *ptr, c = 'r';
strcpy(string, "This is a string");
ptr = strchr(string, c);
if (ptr)
printf("The character %c is at position: %d\n", c, ptr-string);
else
printf("The character was not found\n");
return 0;
}
第九章:结构
一. 定义结构类型与结构变量
在Turbo C中,结构也是一种数据类型,可以使用结构变量,因此,象其它类型的变量一样, 在使用结构变量时要先对其定义。
定义结构变量的一般格式为:
struct 结构名
{
类型 变量名;
类型 变量名;
...
} 结构变量;
结构名是结构的标识符不是变量名。
类型为第二节中所讲述的五种数据类型(整型、浮点型、字符型、指针型和无值型)。
构成结构的每一个类型变量称为结构成员,它象数组的元素一样,但数组中元素是以下标来访问的,而结构是按变量名字来访问成员的。
下面举一个例子来说明怎样定义结构变量。
struct string
{
char name[8];
int age;
char sex[4];
char depart[20];
float wage1,wage2,wage3;
}person;
这个例子定义了一个结构名为string的结构变量person,如果省略变量名person,则变成对结构的说明。用已说明的结构名也可定义结构变量。这样定义时上例变成:
struct string
{
char name[8];
int age;
char sex[4];
char depart[20];
float wage1,wage2,wage3;
};
struct string person;
如果需要定义多个具有相同形式的结构变量时用这种方法比较方便,它先作结构说明,再用结构名来定义变量。
例如:
struct string Tianyr, Liuqi, ...;
如果省略结构名,则称之为无名结构,这种情况常常出现在函数内部,用这种结构时前面的例子变成:
struct
{
char name[8];
int age;
char sex[4];
char depart[20];
float wage1,wage2,wage3;
} Tianyr, Liuq
结构变量的使用
结构是一个新的数据类型,因此结构变量也可以象其它类型的变量一样赋值、运算,不同的是结构变量以成员作为基本变量。
结构成员的表示方式为:
结构变量.成员名
如果将结构变量.成员名看成一个整体,则这个整体的数据类型与结构中该成员的数据类型相同,这样就可象前面所讲的变量那样使用。
下面这个例子定义了一个结构变量,其中每个成员都从键盘接收数据,然后对结构中的浮点数求和,并显示运算结果。请注意这个例子中不同结构成员的访问。
#include
main()
{
struct
{ /*定义一个结构变量*/
char name[8];
int age;
char sex[4];
char depart[20];
float wage1,wage2,wage3;
}a;
float wage;
char c='Y';
while(c=='Y'||c=='y') /*判断是否继续循环*/
{
printf(\nName:);
scanf(%s, a.name); /*输入姓名,这里的名字是字符数组类型不用加@*/
printf(Age:);
scanf(%d, &a.wage); /*输入年龄这里的年龄是整型要用@*/
printf(Sex:);
scanf(%s, a.sex);
printf(Dept:);
scanf(%s, a.depart);
printf(Wage1:);
scanf(%f, &a.wage1); /*输入工资*/
printf(Wage2:);
scanf(%f, &a.wage2);
printf(Wage3:);
scanf(%f, &a.wage3);
wage=a.wage1+a.wage2+a.wage3;
printf(The sum of wage is %6.2f\n, wage);
printf(Continue?);
c=getche();
}
}
结构数组:
结构数组的声明
首先假如我们定义的book结构体如下:
struct book {
char title[40];
char author[40];
float value;
};
声明一个结构数组与声明一个其他类型的数组的方法是一样的。
struct book library[MAXBKS];//MAXBKS是一个int型的整数
这条语句声明library为一个具有MAXBKS个元素的数组,数组的每个元素都是bbook类型的结构。因此,library[0]是一个book结构,library[1]是一个book结构,以此类推。
嵌套结构:
一个结构中含有另一个结构,称为嵌套结构。
嵌套结构在很多时候是非常有用的,比如要建立一个关于朋友的档案信息的结构,这些信息中肯定要包含名字(name)这个信息,而一个人的名字又包含了姓和名,这时我们就可以把名字(name)本身表示成一个结构,在建立朋友档案结构的时候直接将其包含进去。
首先建立一个name结构:
struct name{ //name结构声明
char firstname[20];
char lastname[20];
};
有了name结构,可以在此基础上建立guy结构了:
struct guy{
struct name handle; //结构嵌套,注意这里不用再定义handle的类型,直接这样表示即可。
char favfood[20];
char job[20];
float income;
};
嵌套结构如何初始化?
初始化方法与普通的结构体初始化方法相同:
struct guy fellow = { //初始化变量
{"xu","song"},
"hambergers",
"student",
23.00
};
嵌套结构中的成员操作:
fellow.handle.firstname //运行结果:xu
fellow.handel.lastname //运行结果:song
fellow.favfood //运行结果:hambergers
fellow.job //运行结果:student
fellow.income //运行结果:23.00
typedef struct与struct 的关系:
typedef是类型定义的意思。typedef struct 是为了使用这个结构体方便。
具体区别在于:
若struct node {}这样来定义结构体的话。在申请node 的变量时,需要这样写,struct node n;
若用typedef,可以这样写,typedef struct node{}NODE; 。在申请变量时就可以这样写,NODE n;
区别就在于使用时,是否可以省去struct这个关键字。
在C中定义一个结构体类型要用typedef:
typedef struct Student
{
int a;
}Stu;
于是在声明变量的时候就可:Stu stu1;
如果没有typedef就必须用struct Student stu1;来声明
这里的Stu实际上就是struct Student的别名。
另外这里也可以不写Student(于是也不能struct Student stu1;了)
typedef struct
{
int a;
}Stu;