------- iOS培训、PHP培训、android培训、java培训、期待与您交流! ----------
说明:
1、 字符串
2、 字符与字符串常用处理函数
3、 预处理指令1—宏定义:
4、 预处理指令2—条件编译:
5、 预处理指令3—文件包含:
6、 static 和 extern 关键字1—对函数的作用:
7、 static 和 extern 关键字1—对函数的作用:
(一) 字符串
1、 字符串简介:C语言中,由一个或多个字符组成的序列,使用字符数组存储字符串;
1> 字符数组以’\0’标识结束(ASCII中的0字符,空操作符),若无此结束标记,说明此字符数组存储的非字符串;
如:char a[] = mj;
2、 字符串的初始化:
1> char a[3] = {‘m’,’j’,’\0’};
2> char b[3];
b[0] = ‘m’;
b[1] = ‘j’;
b[2] = ‘\0’;
3> char c[3] = ”mj”; // 系统自动添加\0结束符
4> char d[] = ”mj”;
5> char e[20] = ”mj”;
3、 字符串的输出:
1> 可使用stdio.h中的printf和puts函数输出字符串;
2> 使用格式符:%s表需输出一个字符串,直到\0字符为止,但不输出空字符;
3> printf函数:可同时输出多个字符串;
4> puts函数:一次只能输出一个字符串,且输出一个字符串后自动换行;
4、 字符串的输入:
1> 可使用stdio.h中的scanf和gets函数输入字符串;
2> 字符串输入:从a的首地址开始存放用户输入的字符,存放完毕后,系统会自动在尾部加上结束标记\0;
3> scanf函数:可同时读取多个字符串,且不能读取空格、tab的字符串;
4> gets函数:一次仅能读取一个字符串,且能读入包含空格、tab的字符串;
5、 字符串数组:
1> 字符串数组简介:一维数组存放一个字符串,二维数组存放多个字符串(依次累加);
2> 字符串数组的初始化:
如:char names[2][10] = {{‘j’,’a’,’y’,’\0’},{‘j’,’i’,’m’,’\0’}};
char names[2][10] = {{“jay”},{“jim”}};
char names[2][10] = {“jay”,”jim”};
(二) 字符与字符串常用处理函数
1、 字符处理函数:
1> 可使用stdio.h中的字符输出函数putchar和 字符输入getchar函数处理字符;
2> 字符输出函数putchar:
① 用法:putchar(65); // 输出A
putchar(‘A’); // 输出A
int a = 65; putchar(a); // 输出A
② putchar一次仅能输出一个字符,ptintf可同时输出多个字符;
3> 字符输入函数getchar:
① 用法::char c; c = getchar();
② getchar 一次仅能读入一个字符,且可读入空格、tab,直到遇到回车符为止;
scanf 可同时接收多个字符,且不能读入空格、tab、回车换行符;
③ getchar还可读入回车换行符,你需敲2次回车,第1次敲被getchar读入,第二次代表输入结束;
2、 字符串处理函数:
1> 常用string.h中字符串处理函数:strlen 、strcpy;
2> strlen 函数:测量字符串的字符个数,直到遇到\0为止,但不包括\0;
① 用法:int size = strlen(“mj”); //长度为2
char s1 = “mj”; int size1 = strlen(s1) ; //长度为2
char s2 = {‘m’,’j’,’\0’,’l’,’m’,’j’,’\0’}; int size2 = strlen(s2) ; //长度为2
3> strcpy 函数:拷贝字符串至字符数组,直到遇到\0为止,保留\0至数组中;
① 用法:char s[10]; strcpy(s,”mj”); // 拷贝m/j/\0至s数组中
char c[] = {‘m’,’j’,’\0’,’l’,’m’,’j’,’\0’}; strcpy(s,c); // 拷贝m/j/\0至数组
4> strcat 函数:拼接字符串2至字符数组尾部,直到遇到\0为止,但\0被覆盖后,数组末尾保留\0;
① 用法:
。char s1[30] = “LOVE”; strcat(s1,”OC”); //s1为LOVEOC\0
。char s1[30] = {‘L’,’O’,’V’,’E’,’\0’,’J’,’A’,’\0’};
。strcat(s1,”OC”);//s1为LOVEOC\0
5> strcmp 函数:比较2个字符串大小;
① 调用形式:strcmp(字符串1,字符串2);
② 从左往右逐个字符比较(ASCII码值大小),直到字符不同或遇到\0为止,若所有字符相同则返回0,不同则返回2个字符串中第一个不同字符ASCII码值的差(字符串1>字符串2返回正,否则返回负);
③ 用法:char s1[]=“abc”; char s2=“abc”; char s3=“aBc”; char s4=“ccb”;
int result1 = strcmp(s1,s2); // 相同为0
int result2 = strcmp(s1,s3); // 不同,返回第一个不同字符的码值差b-B=32;
int result3 = strcmp(s1,s4); // 不同,返回第一个不同字符的码值差a-c=(-2);
(三) 预处理指令1—宏定义:
1、 预处理指令简介:
1> C语言中,对源程序编译之前会对一些特殊的预处理指令作解释(如:#include文件包含指令),产生一个新源程序(这个过程称编译预处理),之后再进行编译;
2> 预处理指令一般以符号”#”开头,且结尾不用分号;
3> 预处理指令可出现在程序任意位置,作用范围是从它出现位置到结尾,习惯上尽可能的写在程序开头,其作用为整个程序;
4> C语言提供的预处理指令主要有:宏定义、文件包含、条件编译;
2、 不带参数的宏定义:
1> 一般形式:#define 宏名 字符串
如:#define ABC 10 // 左边字符串可省略为:#define ABC
2> 作用:在编译预处理时,将源程序所有”宏名”替换成右边的”字符串”,常用来定义常量;
3> 使用习惯与注意:
① 宏名一般大写,但小写也无语法错误;
② 对程序中用双引号括起来的字符串内的字符,不进行宏的替换操作;
如:#define R 10 char *s = “Radio”;
③ 在编译预处理用字符串替换宏名时,不做语法检测,只是简单的字符串替换;仅在编译时才对已展开宏名的源程序进行语法检查;
④ 宏名的有效范围:从定义位置到文件结束,若需终止宏定义作用域,可用#undef 宏名 命令;
⑤ 定义一个宏时,可引用已经定义的宏名
3、 带参数的宏定义:
1> 一般形式:#define 宏名(参数列表) 字符串;
2> 作用:在编译处理时,将源程序中所有宏名替换成字符串,并将 字符串中的参数 用 宏名右边参数列表 中参数替换;
如:#define average(a,b) (a+b)/2 int a = average(10,5);
3> 使用注意:
① 宏名和参数列表间不能有空格,否则空格后的所有字符串都作为替换的字符串;
如:如:#define average (a,b) (a+b)/2 //绿色地方不能有空格
② 带参数的宏在展开时,只作简单的字符和参数的替换,不进行任何计算操作。因此,在定义宏时,一般用一个小括号扩住字符串的参数;
如:#define D(d) 2*(a)
③ 计算结果最好也用括号括起来;
如:#define Pow(a) ((a) * (a))
4> 与函数的区别:
带参数的宏定义,在源程序中出现的形式与函数很像,但两者有本质的区别:
① 宏定义不涉及存储空间的分配、参数类型匹配、参数传递、返回值问题;
② 函数调用在程序运行时执行,而宏替换只在编译预处理阶段进行,所以带参数的宏比函数具有更高的执行效率;
(四) 预处理指令2—条件编译:
1、 条件编译:希望程序的其中一部分代码只有在满足一定条件时才进行编译,否则不参与编译(只有参与编译的代码最终才被执行),这就是条件编译;
2、 基本用法:
1> 如:
2> 条件几成立就把该条件中的code代码编译进去(编译进去,不是执行);
3> 条件编译结束后,在后面加上#endif;
4> #if 和 #elif 后面的条件一般是判断宏定义,而不是判断变量,因为条件编译器在编译前做的判断,宏定义也是编译前定义的,而变量是在运行时才产生的、才有使用意义的;
3、 例子解析:
4、 其他用法:
① #if defined() 和 #if !defined() 语法:
。#if 和 #elif后的条件不仅可用来判断宏的值,还可判断是否定义过某个宏;
如图:若前面已定义过MAX宏,就将code编译进去(只要定义过MAX,则条件就成立)
。条件可取反;
如图:若前面没有定义过MAX这个宏,就将code编译进去;
② #ifdef 和 #ifndef的使用:
。#ifdef 的使用 和 #if defined() 用法基本一致;
如图:若前面已定义过MAX宏,就将code编译进去(只要定义过MAX,则条件就成立)
。#ifndef的使用 和 #if !defined() 用法基本一致;
如图:若前面没有定义过MAX这个宏,就将code编译进去;
(五) 预处理指令3—文件包含:
1、 基本概念:使用文件包含指令#include,将一个文件的全部内容拷贝到另一文件中;
2、 一般形式:
1> 调用系统库函数头文件所在目录寻找文件:#include <文件名>;
2> 系统先在源程序当前目录下查找,在到操作系统path路径中查找,最后到库函数文件所在目录中查找:#include “文件名”;
3、 使用注意:
1> #include 指令允许嵌套包含:如a.h 包含 b.h;
2> 使用#include 指令可能导致多次包含同一头文件,降低编译效率;
3> 解决重复包含头文件问题:
(六) static 和 extern 关键字1—对函数的作用:
1、 extern 与函数:
1> 了解:
① 外部函数:若在当前文件中定义的函数允许其他文件访问、调用,就为外部函数。C语言规定,不允许有同名的外部函数;
② 内部函数:若当前文件中定义的函数不允许其他文件访问、调用,只能在内部使用,就称为内部函数。C语言规定不同源文件可有同名的内部函数,且互不干扰;
③ 编译:单独检查每个源文件语法是否合理,不会检查每个源文件间的管理关系,一个源文件编译成功就生成一个目标文件;
④ 链接:检查目标文件的关联关系,将相关联的目标文件组合在一起,生成可执行文件;
2> 外部函数:
① 定义:使用extern关键字(默认为外部函数,extern关键字可省略);
如:extern void one(){};
② 声明:在main函数前对该函数进行提前声明:应使用extern关键字,表引用别人的”外部函数”;
如:extern void one();
③ 调用:使用#include “**.c” 文件包含指令;
④ 注意:extern可省略不写,函数默认为外部函数;
2、 static 与函数:
1> 内部函数定义:使用static关键字定义内部函数;
如:static void one(){}
2> 声明内部函数:在main函数前对该函数进行提前声明:static void one();
3> 调用:使用#include “**.c”;
3、 static、extern 与函数的总结:
1> static:
① 在定义函数时,在函数最左边加上static可把该函数声明为内部函数(也叫静态函数),该函数就只能在其定义所在文件中使用,若不同文件中有同名内部函数,互补干扰;
② static也可声明一个内部函数;
2> extern:
① 在定义函数时,若在函数最左边加上关键字extern,则表示此函数是外部函数,可供其他文件调用,C语言规定,若在定义函数时省略extern,则隐含为外部函数;
② 在一个文件中要调用其他文件中的外部函数,则需在当前文件中用extern声明该外部函数,然后可使用,这里的extern可省略;
(七) static 和 extern 关键字1—对函数的作用:
1、 C语言中,全局变量定义的位置是有限制的(java中无严格限制):
1> 默认情况下,一个函数不可访问在它后面定义的全局变量;
2> 可使用解决方法:
① 将变量定义在main函数前;
② 在main函数前对变量进行提前声明(使用关键字extern);
2、 重复定义同一变量:
1> 重复定义表同一变量;
3、 不同源文件的同名变量:
1> 不同源文件的同名变量,表同一变量;
4、 static关键字:
1> 不想源文件中的全局变量与其他源文件共享,相当于私有的全局变量,就使用static关键字来定义变量;
2> extern是用来声明已经定义过且能够访问的变量;
5、 static和extern的总结:
1> extern可用来声明一个全局变量,但不能用来定义变量;
2> 默认情况下,一个全局变量可供多个源文件共享的,也就是说,多个源文件中同名的局部变量都代表同一变量;
3> 若在定义全局变量时加上static关键字,此时static的作用在于限制该全局变量的作用域,只能在定义该全局变量的文件中才能使用,跟其他文件中的同名变量互补干扰;
PS:这节总结了关于字符串、预处理和extern/static关键字的作用,这节也需要掌握。
这里就是我总结的所有有C语言知识点,当然重要的是:函数、预处理、指针、数组、枚举、结构体等重要知识点需要掌握哟!
------- iOS培训、PHP培训、android培训、java培训、期待与您交流! ----------