1.C语言的数据类型:
整型,字符型,浮点型,枚举类型,数组类型,结构体类型,共用体类型,指针类型,空类型。
基本类型:整型,字符型,浮点型,枚举类型,。
构造类型:数组类型,结构体类型,共用体类型。
指针类型
空类型
2.数组VS链表:
数组:具有相同数据类型的元素按一定顺序排列的集合。
①数据顺序存储,存储空间是连续的。
②数组中的元素都是相同类型的。
③数组的长度是固定的。
④数组的空间是从栈分配的。
⑤查找快,增删慢。
链表:链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
①链表的元素是通过指针进行连接的,不是顺序存储的,内存空间不一定连续。
②元素可以是不同类型的。
③链表的长度是可变的。
④链表的空间是从堆中分配的。
⑤增删快,查找慢。
3.数组的分类:
数组的分类主要是:静态数组、动态数组两类。
静态数组:类似int arr[5];在程序运⾏就确定了数组的⼤⼩,运⾏过程不能更改数组的⼤⼩。
动态数组:主要是在堆区申请的空间,数组的⼤⼩是在程序运⾏过程中确定,可以更改数组的⼤⼩。
4.、描述⼀下⼀维数组的不初始化、部分初始化、完全初 始化的不同点。
不初始化:如果是局部数组 数组元素的内容随机 如果是全局数组,数组的元素内容为0 。
部分初始化:未被初始化的部分⾃动补0 。
完全初始化:如果⼀个数组全部初始化 可以省略元素的个数 数组的⼤⼩由初始化的个数确定。
5、谈谈数组名作为类型、作为地址、对数组名取地址的 区别?
数组名作为类型:代表的是整个数组的⼤⼩
数组名作为地址:代表的是数组⾸元素的地址
对数组名取地址:代表的是数组的⾸地址
6、谈谈你对⼆维数组在物理上以及逻辑上的数组维度理解.
⼆维数组在逻辑上是⼆维的,在物理上是⼀维的.
7、描述⼀下指针与指针变量的区别:
- 指针:指针也就是内存地址。内存中每⼀个字节都会分配⼀个32位或64位的编号,这个编号就是地址, ⽽指针就是内存单元的编号。
- 指针变量:用来存放内存地址的变量。
8、描述⼀下32位或64位平台下指针的⼤⼩:
32位平台:任意类型的指针⼤⼩为4字节;
64位平台:任意类型的指针⼤⼩为8字节。
9、描述⼀下指针数组的概念.
指针数组本质是数组,只是数组的每个元素是⼀个指针(地址)。
10、哪些情况下会出现野指针?
指针变量未初始化、指针释放后未为置空、指针操作超越变量作⽤域。
11、如何避免“野指针”?
“野指针”产生原因及解决办法如下:
(1) 指针变量声明时没有被初始化。解决办法:指针声明时初始化,可以是具体的地址值,也可让它指向 NULL。
(2) 指针 p 被 free 或者 delete 之后,没有置为 NULL。解决办法:指针指向的内存空间被释放后指针应该指向 NULL。
(3) 指针操作超越了变量的作用范围。解决办法:在变量的作用域结束前释放掉变量的地址空间并且让指针指向 NULL。
注意:“野指针”的解决方法也是编程规范的基本原则,平时使用指针时一定要避免产生“野指针”,在使用指针前一定要检验指针的合法性。
13.程序 = 算法(对操作的描述,即操作步骤)+数据结构(对数据的描述)。
14.算法的特性:
有穷性、确定性、有效性、输入(零个或多个)、输出(一个或多个)。
15、描述算法的常用方法:
自然语言、传统流程图、结构化流程图、伪代码、PAD图。
自然语言特点:通俗易懂;文字冗长,易出现歧义性。
传统流程图:直观形象、易于理解;对流程线的使用没有限制,难以保证算法的可靠性和可维护性。
结构化流程图:去掉了带箭头的流程线,由若干个基本结构构成,比文字更加直观简洁,比流程图更紧凑易画。
伪代码:不用画图,书写格式*,易于修改,也便于向计算机语言过渡。
16.3种基本结构:
顺序结构、选择结构、循环结构。
共同特点:只有一个入口、只有一个出口、结构内的每一部分都有机会执行到、结构内不存在死循环。
17、结构化程序设计方法的思想:C语言就是结构化语言,把一个复杂问题的求解过程分阶段进行,每个阶段处理的问题都控制在人们容易理解和处理的范围内。
18、用(自顶向下,逐步细化,模块化设计,结构化编码)的方法来保证得到结构化的程序。
19、编码:将已经设计好的算法用计算机语言表示。
20、常量:程序运行过程中,其值不能被改变的量。变量:代表内存中具有特定属性的一个存储单元。用来存放数据,数据的值在程序运行期间可以改变。
21、变量的命名规则:
由字母、数值、下划线组成,但不能以数值开头。
22、变量的声明与定义有啥区别?
声明变量不需要建⽴存储空间,变量的定义需要建⽴存储空间。
一个变量可以在多个地方声明,只能在一个地方定义。
23、谈谈c语⾔中有符号和⽆符号的区别?
有符号:数据的最⾼位为符号位,0表示正数,1表示负数。
⽆符号:数据的最⾼位不是符号位,⽽是数据的⼀部分。
24、谈谈计算机中补码的意义
①统⼀了零的编码。
②将符号位与其他位统⼀处理将减法运算转换成加法运算。
25、什么是指针的指针?
指针的指针是指一个指向指针所在地址的指针。
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
26、C语言特点:
(1)语言简洁,紧凑,使用方便,灵活。
(2)运算符丰富。
(3)数据类型丰富,
(4)具有结构化的控制语句
(5)语法限制不太严格,程序设计*度大。
(6)C语言允许直接访问物理地址,能进行位操作,既具有高级语言的功能,又具有低级语言的许多功能,这种双重性,使它既是成功的系统描述语言,又是通用的程序设计语言。
(7)可移植性好。
(8)生成目标代码质量高,程序执行效率高。
27、计算机算法分两类:
数值运算算法:求数值解。
非数值运算算法:排序、检索、管理。
28、怎样引用指针变量:
(1)&:取地址运算符,&a是变量a的地址。(2)星号:指针运算符或称间接运算符,P代表指针变量p指向的对象。
29、编译预处理不是C语言的一部分,不占运行时间,不要加分号。C语言编译的程序称为源程序,它以ASCII数值存放在文本文件中。
30、注释不是C语言,不占运行时间,没有分号。不可以嵌套!
31、#define PI 3.1415926; 这个写法是错误的,一定不能出现分号。
32、在函数中不可以再定义函数。
33、算法:可以没有输入,但是一定要有输出,没有输出的算法是没有意义的。
34、参数之间的传递:
实参和形参之间 传数值,和传地址的差别。(考试的重点)
传数值的话,形参的变化不会改变实参的变化。
传地址的话,形参的变化就会有可能改变实参的变化。
35、函数声明的字符数组:
C语言中没有字符串变量,字符串是靠字符数组实现的,所谓字符数组就是元素的数据类型为字符型的数组。
一定要有:函数名,函数的返回类型,函数的参数类型。
不一定要有:形参的名称。
36、常用的字符串处理函数:
C语言提供了一些处理字符串的标准函数,用以完成一些常见的操作。对以下几个函数要掌握其功能和调用形式。
(1)gets(字符数组名)此函数功能是从键盘输入一串字符,回车后送到字符数组中,注意定义数组时数组长度要足够大。
gets可以接收空格;而scanf遇到空格、回车和Tab键都会认为输入结束,所有它不能接收空格。
(2)puts(字符数组名)此函数功能是将字符数组的内容输出到屏幕上。
puts()在输出字符串时会将’\0’自动转换成’\n’进行输出,也就是说,puts方法输出完字符串后会自动换行。
(3)strcat(字符数组名1,字符数组名2)此函数功能是将字符数组1中的’\0’去掉后将字符数组2的内容连接到字符数组1的末尾。
(4)strcpy(字符数组名1,字符数组名2)函数功能是将字符数组2的内容(包括’\0’)拷贝到字符数组1中,字符数组2处也可以是字符串常量。strcpy函数可以实现拷子串。
有可能被覆盖
(5)strcmp(字符数组名1,字符数组名2)函数功能是两个字符串(ASCII码)比大小。
(6)strlen(字符数组名)此函数功能是求字符串的长度,注意不包括’\0’。
(7)strlwr(字符数组名)此函数功能是将字符串中的所有大写字母都变成小写。
(8)strupr(字符数组名)此函数功能是将字符串中的所有小写字母都变成大写。
37、&&和&、||和|有什么区别:
(1)&和|对操作数进行求值运算,&&和||只是判断逻辑关系。(2)&&和||在在判断左侧操作数就能确定结果的情况下就不再对右侧操作数求值。
38、#include<> 与#include ""的区别?
include<>到系统指定⽬录寻找头⽂件,#include ""先到项⽬所在⽬录寻找头⽂件,如果没有找再到系统指定的⽬录下寻找。
39、结构体与共⽤体的区别:
结构体中的成员拥有独⽴的空间,共⽤体的成员共享同⼀块空间,但是每个共⽤体成员能访问共⽤区的空间⼤⼩是由成员⾃身的类型决定
40、abs和fabs的区别是什么?
这两个函数都是用来取绝对值的。前者是针对整型的。后者是针对浮点型的。前者位于标准库stdlib.h里面。后者在math.h里面。
41、++a和a++的区别是什么?
加加a的意思是先加后取值。
a加加的意思是先取值后增加。
42、除法运算符与求余运算符:
/ :左右两边都是整数结果只取整数部分;左右两边有一边有小数位,结果也有小数位。
% :正负符号只与被除数(左边)一致。13%(-3)=1;-13%3=-1;-13 % -3=-1;
43、逗号运算符的级别最低,赋值的级别倒数第二。
44、逗号表达式:
优先级别最低。表达式的数值逗号最右边的那个表达式的数值。
(2,3,4)的表达式的数值就是4。
z=(2,3,4)(整个是赋值表达式) 这个时候z的值为4。
z= 2,3,4 (整个是逗号表达式)这个时候z的值为2。
45、字符常量与字符串常量有什么区别?
(1)字符常量是用单引号括起来的一个字符。在存储时,占1个字节。
字符串常量是用双引号括起来的一串字符序列。在存储时,系统自动在字符串尾部加上“\0”作为字符串结束标志。占“字符串长度+1”个字节。
(2)字符常量相当于一个整型值,可以参加表达式的运算;字符串常量代表一个地址值(该字符串在内存中存放的位置)。
字符常量可以赋值给字符变量,如"char b=\'a\';",但不能把一个字符串常量赋给一个字符变量,同时也不能对字符串常量赋值。
- - - - - - - - - - - - - - - - - - - -- - - - -- - -- - - - - ----------------------------------------------------------------------------------------------------- - -
46、对内存空间的访问方式:
直接访问方式:按变量名访问或存取变量值的方式称为直接访问方式。
间接访问方式:先从其它内存空间获得要访问的内存地址,根据得到的地址访问目的地址中的变量值。(将变量a的地址存放在变量b中,通过变量b来找到变量a的地址,从而访问a变量。)
47.*a表示a指向的对象,a叫指针变量,a的值是地址(指针)
48.定义指针变量必须指定基类型:int *a, *b;(int叫基类型)
定义形式为:基类型 *指针变量名1,*指针变量名2……;
49.初始化时:int *p1=&a, *p2=&b;
赋地址时: p1=&a; p2=&b;
50.一个变量的指针的含义包含两个方面
地址:以存储单元编号表示的纯地址。
数据类型:它指向的存储单元的数据类型。
51、不能将一个数值付给指针变量,只能用 &变量 的形式来表示一个变量的地址。如,a的地址单元为2000:
int a;
int * p;
错误:p=2000; 计算机不能将2000识别为地址,会将2000作为一个整数来处理。
正确:p=&a;
52、指针变量做函数的参数:
(1)指针作函数的参数可以将一个变量的地址传送到另一个函数当中,如数组的首地址,函数的入口地址等。
(2)指针作函数的参数也可以用地址方式传送数据。
53、实参和形参是单向“值传递”,不能通过调用函数来改变实参(指针)变量的值,指针变量做参数也要遵循这一规则,但是可以改变实参指针变量所指变量的值。
54、数组元素的指针:数组元素的地址。
55、引用数组元素的方法:
int a[3];int * p;
下表法:a[0];
指针法: (p=&a[0];) *p就代表a[0];
56、在指针指向一个数组元素时可以进行如下运算:
加一个整数,+1代表指向下一个数组元素。
减一个整数,-1代表指向上一个数组元素。
自增
自减
57、两个指针相减(p1-p2)只有在这两个指针都指向同一数组才有意义。
两个指针相加(p1+p2)没有任何意义。
58、[] : 变址运算符:
a+i = &a[i];
*(a+i) = a[i] = *(p+i);(p的初值是&a[0])。
59、*p++:
* 与 ++ 优先级相同,自右向左结合,相当于*(p++),先实现*p运算,再使p自增1。
60. 数组名做函数参数
数组名做形参,被当作指针变量来处理。
fun(int arr[],int n); 等价于 fun(int *arr,int n);
数组名做实参,是一个固定的地址,或者说指针常量。
函数的实参用数组名时,形参可以用数组名也可以用指针变量。
61、二维数组中:
a[0] = &a[0][0]; a[1]= &a[1][0];
a[0] = &a[0][0]; a[0]+1 = &a[0][1]= *(a+0)+1;
62、指向一维数组的指针变量:int (*p)[4];
不可以写成int * p[4];因为[]比*优先级高,这样是定义了一个指针数组。
63、若有一个实参数组,想在函数中改变此数组元素的值,实参和形参的对应关系有以下四种情况:
①实参和形参都用数组名
②实参和形参都用指针变量
③实参用数组名,形参用指针变量
④实参用指针变量,形参用数组名
64、sizeof 和 strlen 有以下区别:
1 sizeof 是一个操作符,strlen 是库函数。
2 sizeof 的参数可以是数据的类型,也可以是变量,而 strlen 只能以结尾为‘\0‘的字符串作参数。
3 编译器在编译时就计算出了 sizeof 的结果。而 strlen 函数必须在运行时才能计算出来。并且 sizeof 计算的是数据类型占内存的大小,而 strlen 计算的是字符串实际的长度。
65.全局变量和局部变量
局部变量(Local Variable):定义在函数体内部的变量,作用域仅限于函数体内部。离开函数体就会无效。再调用就是出错。
全局变量(Global Variable):定义:所有的函数外部定义的变量,它的作用域是整个程序,也就是所有的源文件,包括.c和.h文件。
66.内部函数和外部函数
1.内部函数
如果一个函数只能被本文件中的其他函数所调用,称它为内部函数。内部函数又称为静态函数。在定义内部函数时,在函数名和函数类型前加 static .如下:
static 类型标识符 函数名 ()
{
函数体。
}
使用内部函数,可以使函数的作用域只局限于所在文件,在不同的文件中又同名的内部函数,互不干扰。通常把只能由同一文件使用的函数和外部变量放在一个文件夹中,在它们前面加上static使其局部化,其他文件不能调用。
2.外部函数
除内部函数外,其余的函数都可以被其他文件中的函数所调用,同时在调用的函数的文件上应加上 extern 关键字说明。定义如下:
extern 类型标识符 函数名 ()
{
函数体。
}
c语言规定,如果在定义函数时省略 extern ,则默认为外部函数。
67.编译预处理(预处理和预编译)分为:宏定义、文件包含、条件编译
宏定义:例如 #define PI 3.1415926 #define PI 标识符 字符串
宏名的有效范围为该指令行起到本源文件结束。
“文件包含”处理“:例如#include”文件名“
指一个源文件可以将另外一个源文件的全部内容包含起来,即将另外的文件内容包含到本文件中。
条件编译希望在满足某条件时对某一组语句进行编译,而当条件不满足时则编译另一组语句。
#ifdef 标识符
程序段 1
#else
程序段2
#endif
68。文件的分类:文本文件和二进制文件
69。补码的计算方式:
(1)正数的补码:与原码相同。
【例1】+9的补码是00001001。
(2)负数的补码:符号位为1,其余位为该数绝对值的原码按位取反;然后整个数加1。
【例2】求-7的补码。
因为给定数是负数,则符号位为“1”。
后七位:+7的原码(0000111)→按位取反(1111000)→加1(1111001)
70..C程序运行步骤是编辑、编译、连接、执行。
编辑后得到一个源文件 f.c 源文件
然后再对源文件编译 生成目标程序文件 .obj 目标文件
然后将所有的目标模块输入计算机,与系统提供的库函数进行连接,得到可执行的目标文件 。exe 可执行文件
最后把可执行文件输入计算机,运行后得到结果。
71.强制类型转换和自动类型转换
- 自动转换发生在不同数据类型的量混合运算时,由编译系统自动完成。自动转换遵循以下规则:若参与运算量的类型不同,则先转换成同一类型,然后进行运
- 强制类型转换是通过类型转换运算来实现的。其一般形式为: (类型说明符) (表达式) 其功能是把表达式的运算结果强制转换成类型说明符所表示的类型。