
c/c++ 初学者必看的知识点整理
5星
- 浏览量: 0
- 大小:None
- 文件类型:DOC
简介:
对下列数据类型进行说明:
(1) float (**def)[10];
def是一个二级指针变量,它指向一个一维数组的指针,该数组中的元素全部是float类型的数据。
(2) double*(*gh)[10];
gh是一个指针变量,这个指针指向的是一个一维数组。尽管这个数组本身没有数据类型声明,但它存储的是double类型的指针。
(3) double(*f[10])();
f是一个包含有十个元素的数组,这些元素都是函数的指针变量。每个函数必须不接受任何参数,并且返回值是double类型的数据。
(4) int *((*b)[10]);
这个表达式等价于int *(*b)[10];这里的b是一个指向一维整数数组的指针变量。
(5) Long (*fun)(int);
这是一个函数指针变量,它接收一个整型参数并返回Long类型的值。
(6) int((*(*F)(int,int))(int));
F是一个函数指针变量,这个函数指针指向另一个函数。被指向的函数有两个整型参数,并且返回的是一个函数指针变量;而该返回的函数指针又指向了一个接收单一整型参数并返回整型值的函数。
所有的ASCII码都可以用“”加数字(一般是8进制数字)来表示。而C中定义了一些字母前加来表示常见的那些不能显示的ASCII字符,如0,t,n等,就称为转义字符,因为后面的字符,都不是它本来的ASCII字符意思了。
转义字符 意义 ASCII码值(十进制)
a 响铃(BEL) 007
b 退格(BS) 008
f 换页(FF) 012
n 换行(LF) 010
r 回车(CR) 013
t 水平制表(HT) 009
v 垂直制表(VT) 011
反斜杠 092
? 问号字符 063
单引号字符 039
双引号字符 034
0 空字符(NULL) 000
ddd 任意字符 三位八进制
xhh 任意字符 二位十六进制
字符型常量
字符型常量所表示的值是字符型变量所能包含的值。我们可以用ASCII表达式来表示一个字符型常量,或者用单引号内加反斜杠表示转义字符。
A, x2f, 013;
其中:x表示后面的字符是十六进制数,0表示后面的字符是八进制数。
注意:在Turbo C 2.0中,字符型常量表示数的范围是-128到127,除非你把它声明为unsigned,这样就是0到255。
上面我们见到的x,n,a等等都是叫转义字符,它告诉编译器需要用特殊的方式进行处理。下面给出所有的转义字符和所对应的意义:
转义字符 描述
单引号
双引号
反斜杠
0 空字符
ccc (最多三位)八进制数
a 声音符
b 退格符
f 换页符
n 换行符
r 回车符
t 水平制表符
v 垂直制表符
xhh(最多两位)十六进制符在代码输出方面,我们需要从以下几个关键点进行分析:
第一部分:关于sizeof()与strlen()的应用场景及功能差异:
1. 从功能定义上来看,strlen函数的作用是获取字符串的实际长度,而sizeof函数则是计算指定变量或类型所占的内存大小。具体而言,在静态数组处理中,当使用char str[20]= 0123456789时,strlen(str)返回10,表明该字符串的长度;而sizeof(str)则给出20,反映整个数组所占内存空间。
第二部分:对指针与非指针变量处理方式的区别:
在动态数据结构处理中:
- 对于指针型变量(如char *str= 0123456789),strlen(str)的结果仍然是10,这表明字符串的实际长度;而sizeof(str)返回的是4,这是指针变量所占的内存空间大小。此外,针对单个字符类型的引用(*str),其占用的空间为1字节。
第三部分:关于结构体与类的基本区别:
在面向对象编程中:
- 类成员默认实现为public访问权限;同时允许用户根据需要将其设置为private或protected。相比之下,结构体定义的成员始终具有public属性。
- 在继承机制上存在显著差异:结构体不支持继承功能,而类则能够实现多个层次的继承。
第四部分:函数库中的字符操作函数对比:
1. strcpy()与strncpy()的区别在于参数类型:strcpy接受单指针型指针(char*),而strncpy则需要双指针型指针(const char**)。
2. strcasecmp与strcmp的主要区别在于比较大小写:strcasecmp对输入字符串的大小写进行调整,使其统一为大或小写后再进行比较;而strcmp则是直接基于原始字符值进行对比。
3. 字符串操作函数间的相似性:
- strlen()、strncsptr(), strnrmptr()均以数字结尾,且参数类型均为char*。
- strnlen()则采用双指针型指针(const char**)作为输入参数。4、 内存的分配方式的分配方式有几种?
答: (1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量。
(2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
(3)从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。
5,、解释堆和栈的区别?
答: (1)栈区(stack):由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
(2)堆区(heap):一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表.(主要有:mallocfree,newdelete)
6,、枚举的用法,以及它与宏的区别?
答: 枚举(enum)作用:定义一组常量,而且这些常量组成了一个集合。当我们将emun参数传递给函数时,如果传递了一个不属于这个集合的参数,编译器报错。
区别:
枚举是类型,而宏没有类型。
枚举将检查其语法,而宏是简单的文本替换。
7、 const的用法,以及声明const变量与宏的区别?
答: const的用法有四种:
a): const对象和const类型的对象;
b): const指针 和 指向const的指针 及两者结合;
c): const 参数修饰 和 参数返回类型的const修饰;
d): const类成员 和 const 成员函数;
区别: const常量有数据类型, 而宏常量没有数据类型。编译器可以对前者进行类型安全检查,而对后者只能进行字符 替换,没有类型 安全检查。而且字符替换可能会带来料想不到的边界效应。有些集成化工具可以对const常量进行调试, 但不能对宏量进行调试。
8、函数assert的用法?
答:断言assert是仅在debug版本起作用的宏,用于检查“不应该“发生的情况。程序员可以把assert看成一个在任何系统状态下都可以安全使用的无害测试手段。
9、用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)?
答: #define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL
10、 写一个标准宏MIN,这个宏输入两个参数并返回较小的一个?
答: #define MIN(A,B) ((A) <= (B) ? (A) : (B))
11、嵌入式系统中经常要用到无限循环,你怎么样用C编写死循环呢?
答: 这个问题用几个解决方案。我首选的方案是:
while(1)
{ }
一些程序员更喜欢如下方案:
for(;;)
{ }
13、关于内存对齐的问题以及sizof()的输出?
答: 编译器自动对齐的原因:为了提高程序的性能,数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;然而,对齐的内存访问仅需要一次访问。
14、 static有什么用途?(请至少说明两种)
答: (1)在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。
(2) 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。
(3) 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用。
15、引用与指针有什么区别?
答: (1) 引用必须被初始化,指针不必。
(2) 引用初始化以后不能被改变,指针可以改变所指的对象。
(3) 不存在指向空值的引用,但是存在指向空值的指针。
16、什么是平衡二叉树?
答: 左右子树都是平衡二叉树 且左右子树的深度差值的绝对值不大于1。
17、堆栈溢出一般是由什么原因导致的?
答: 没有回收垃圾资源。
18、什么是预编译?何时需要预编译?
答: (1)总是使用不经常改动的大型代码体。
(2)程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下,可以将所有包含文件预编译为一个预编译头。 19、队列和栈有什么区别?
答: 队列先进先出;栈后进先出。
20、数组和链表的区别?
答: 数组:数据顺序存储,固定大小;
链表:数据可以随机存储,大小可动态改变;
21、为什么数组名作为参数,会改变数组的内容,而其它类型如int却不会改变变量的值?
答: 当数组名作为参数时,传递的实际上是地址。而其他类型如int作为参数时,由于函数参数值实质上是实参的一份拷贝,被调函数内部对形参的改变并不影响实参的值。
22、数据结构和算法:
A:查找:
(1)二分法查找;
B:写出下列算法的时间复杂度和实现排序:
(1)冒泡排序; (2)选择排序; (3)插入排序; (4)快速排序; (5)堆排序; (6)归并排序;
23、编写gbk_strlen函数,计算含有汉字的字符串的长度,汉字作为一个字符处理;已知:汉字编码为双字节,其中
参数里涉及指针,就要考虑该指针是不是一个需要修改的量,如果是,则参数应采用指向指针的指针。
(C语言里参数传递都是传值,是一个拷贝,修改指针,只是改变了拷贝的指向,原指针指向并没有改变,而修改指针的内容则是可以的。)如果函数的参数是一个指针,不要指望用该指针去申请动态内存。(即上面所说的修改该指针)
编译器总是要为函数的每个参数制作临时副本,指针参数p的副本是 _p,指针参数也不例外。
如果非得要用指针参数去申请内存,那么应该改用“指向指针的指针”,由于“指向指针的指针”这个概念不容易理解,我们也可以用函数返回值来传递动态内存。
常常有人把return语句用错了。这里强调不要用return语句返回指向“栈内存”的指针,因为该内存在函数结束时自动消亡。
c语言里,利用函数的返回值来表明它是否执行成功的做法最常见。
2.如果要在单链表中删除或插入一个元素,就必须知道指向删除点或插入点前面那个元素的指针才行。
数组具有随机存取性(可以立即存取任一元素)
char *str = the word
常量字符串,静态存储区,具有程序生命期。
char *str = (char *)malloc(....);
堆上分配,手动释放,否则内存泄漏。
char str[] = the word
栈上分配,函数生命期。
4.
0不是指ASCII码值,它是字符,它的ASCII码值是0,也就是ASCII码表的第一个字符。0并非是空格,空格的ASCII码值是32,只不过是输出类似于空格而已。
5.
在32位程序里,所有类型的指针的值都是一个32位整数,因为32位程序里内存地址全都是32位长,指针本身占据了4个字节的长度,即用一个字的空间保存一个地址。地址是按字节表示的,一个字节一个地址。地址+1,移动一个字节。第6条:从语义上看,在指针声明语句中删除指针标识符及其左侧的*符号,剩下的部分即为该指针所指向的数据类型。p的结果是被指向的内容。
当创建了一个数组TYPE并命名其为array,并且在其中定义了n个元素时,那么array这一名称同时具有双重含义:首先,它代表整个数组本身;其次,它也是一个指针变量,其数据类型为TYPE*。这个指针所指向的内存区域正是存放数组中各个元素的空间(从第0号单元开始),而且该指针本身占据了一块独立的内存空间。
在表示形式 sizeof(array) 中,数组名 array 表示该数组,其测量结果即为此数组的空间占用。 sizeof(array + n) 的测量结果即此指针类型的大小。
每个字符占用一个字节的空间,而整数占据四个字节的内存空间,简称为一个字。为了获取数据类型的大小信息,在编程中可以使用函数sizeof()来实现。该函数返回的结果是以字节为单位的数值。例如,在C语言中,int类型对应的变量会分配出四个连续的字节存储空间。
字符指针与字符串类型在本质上是相同的,它们都用于表示一串连续的字符数据。字符数组占用了十个连续的空间单元,每个单元存储一个字符信息。为了确保程序正确运行,对这些细节进行准确描述和说明是非常必要的。
变量声明和定义是编程语言中最基础的概念,在C++中尤其如此。通过详细解释各种类型的特点及其应用场景,可以帮助开发者更好地理解和掌握编程的基本规则。
a) integer type variable(int变量): `int a;` 它被定义为一个用于存储整数值的变量。代码示例中的`int a;`表明该变量能够容纳表示整数的数据类型信息。b) An integer pointer: `int *a;` the variable `a` is defined as a pointer to an integer type, indicating that it points to an integer variable.
c) A double pointer mechanism is used to point to another pointer, which in turn points to an integer variable. The declaration `int **a;` defines a variable `a`, serving as a pointer that can navigate through layers of pointers until it ultimately references an integer value.
4. d) 包含着10个整数的数组(An array of 10 integers): `int a[10];` 被定义为名为a的数组。其中包含了10个整型数据项。一个包含十个指向整型变量的指针数组:通过以下语句实现了`int *a[10];`。该结构通过以下语句实现了:每个指针都指向一个整型变量。6. f) 一个指向长度为10的整型数组的指针: `int (*a)[10];` 被命名为`a`,其中每个元素都是整数,并且这些元素构成一个长度为10的数组。一个指针变量`a`指向了一个函数,该函数接受一个整型参数并返回值为整型的结果:`int (*a)(int);`描述了其定义和功能特性。一个包含十个指针变量的数组被定义为整型类型(`int (*a[10])(int);`),其中每个指针变量指向一个函数体。这些函数体接收一个整数参数并且返回一个整数值。这个结构被用来实现一组十大小型函数,它们共享相同的参数和返回类型,并且通过指针变量进行间接调用。对于数据声明的说明:`float型数组的二级指针`def`是一个被赋值于浮点数类型的指针变量,并包含一个长度为10的单层指针。`double*(*gh)[10];` 这是一个指针数组。其中,它指向一个名为gh的数组对象本身。这个数组由多个元素组成,每个元素都是双精度浮点数类型,并且它们都被初始化为null或未赋值的状态。`double(*f[10])();`其中,f是由一个包含10个元素的数组构成,每个元素都指向对应类型的功能块。这些功能块均不接受任何输入且返回值为双精度浮点数。该变量是一个指向`int`的指针数组。它等价于通过表达式(*b)[10]所表示的一个长度为10的指针数组。每个元素都指示着内存中对应的整数值。`Long (*fun)(int);` 其中 fun 是一个指向器变量。它是一个函数指针,该函数接收一个 int 类型参数并返回 Long 类型值。`int (*(*F)(int,int))(int);` 函数指针F对应一个能够接收两个整数参数并返回另一个函数指针的函数后端。该函数后端则支持接收单个整数参数并输出结果。
C语言中的转义字符被用来表示特殊的字符。这些特殊用途的字符分别由相应的转义序列来实现。例如,`n`会被用作换行符,而`t`则用于制表符的功能;此外,一个空格也可以通过使用`0`这一特定的转义方式来实现。关于字符型常量的表示方法,可以采用八进制或十六进制形式,并且每个特殊目的都有对应的转义方式:例如,使用017来表示十进制的15。CC++内存的分配方式主要包括静态存储空间(涉及全局变量和静态变量)、栈内存(由编译器自动完成局部变量的内存管理)以及堆内存(需人工进行内存分配,常用`malloc`或`new`函数操作)。其中,栈内存的分配由编译器自动完成,而堆内存则需要程序员进行手动管理。结构体与类的核心差异在于默认访问权限及成员函数的定义方式。在C++语言中,结构体成员默认为公共可见(public),而类则可进行功能继承。需要特别指出的是,在类体系中,成员函数和数据成员的保护级别均被严格限定,以确保程序的安全性和灵活性。相比之下,结构体不具备继承机制,并且其数据成员默认不可见。`sizeof()`运算符用于获取变量或类型所占的内存空间(单位为字节),而`strlen()`函数的作用是计算字符串的实际长度,其中终止字符为`\0`。enums(枚举)被用来定义一组具有固定值的常量,在编程语言中,这些常量拥有明确的数据类型。而macros(宏)则是在预处理阶段进行文本替换操作,不涉及类型检查。JavaScript中的`const`关键字被用来声明常量。它不仅适用于普通的变量,还可以用在指向对象的指针上以及作为函数参数。通过这种机制,在声明常量时能够进行类型检查。相较于传统的宏方式,JavaScript中的`const`关键字在编译阶段就进行了严格的类型验证。该预定义指令的作用是对常量进行声明,举个例子来说,可以用来计算每年的秒数而不考虑闰年情况。具体的实现方式是通过`#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL`来完成。
`MIN`宏其主要作用是获取较小区块,其定义如下:`#define MIN(A,B) ((A) <= (B) ? (A) : (B))`。在C语言中,无限循环通常采用`while(1)`或`for(;;)`进行实现。
内存对齐旨在优化程序执行效率,以保证数据按照预先定义的内存对齐方式进行存储。`sizeof()`函数计算的结果将遵循特定的数据对齐要求。`static`关键字具有多重功能,在函数内部创建静态变量时可保持其值在跨调用期间不变,并且同时允许在模块层面定义私有属性和方法。此外,它还能用于实现类内的静态方法或全局静态常量的定义。参考项(references)与指针类似,但引用必须在声明时初始化且不能重新绑定,而指针可以改变所指的对象。平衡二叉树(包括AVL树和红黑树)是一种严格保持左右子树高度均衡的搜索树结构。通过将左右子树的高度差异控制在最小值内,该数据结构确保了数据查找速度最快。堆栈溢出是由于局部变量过大或递归过深导致栈空间不足。预先处理工作(preprocessing)是在进行编译之前完成对宏替换和包含文件等的处理,有助于提升程序运行速度。队列遵循先进先出(FIFO)的顺序,在这种数据结构中,元素按照到达时间排序;栈则遵循后进先出(FILO)的方式操作,在这种存储和组织数据的方式中,最新的元素总是最先被处理。在数据结构中,数组与链表的核心差异主要体现在存储模式以及访问速度上。具体而言,在数组这种线性存储方式下,元素是按顺序连续存储的,因此其访问速度较快;然而,由于数组的大小是固定的,在扩展或缩减时会遇到一定的限制。相比之下,链表采用的是非连续存储方式,在这种结构下,插入和删除操作较为灵活;但是由于其元素在物理内存中的位置并不固定,因此访问速度较数组更慢。在传递给函数或操作时,其地址是该数组起始位置的内存块,因此可以修改该数组的内容。
数据结构和算法中的搜索方式,例如二分查找法。涉及排序算法的包括冒泡排序、选择排序、插入排序、快速排序、堆排序以及归并排序等,每种排序算法具有不同的时间性能特点以及适应特定数据规模场景的需求。在开发`gbk_strlen`函数时,应特别注意遇到的汉字,这些汉字占用了两个字节,必须确保能够正确处理。在学习C语言指针使用的过程中,涉及动态内存分配的场景以及对指针进行修改的操作时,需要区分指针副本与原始指针之间的区别,并且要注意区分指针与其指向的对象间的不同。
在CC++学习过程中有一些核心知识要点。对于初学者而言,这些都是不可或缺的基础知识。掌握这些知识点则是成为一名熟练的CC++程序员的前提条件。
全部评论 (0)


