C/C++的基础指针知识,帮我看看解释的对吗?

假设我已经基于一个基本类定义了两个类:

然后现在有一个名为Collect的类,它包含指向Basic

在这个类中,定义了一个函数run(),它将根据指针指向的对象类型执行一些操作:

  • 使用C ++,是否可以知道指针指向的对象类型?
  • 根据run函数中所示的指针所指向的对象类型执行不同的操作是不错的做法?

要执行这样的检查,您的基类Basic需要至少有一个虚拟成员。由于您希望构建一个类层次结构,我倾向于使~Basic虚拟,以确保它同时为。

这背后的原因是,通过包含virtual成员,您强制类的每个对象包含指向特定类的指针,然后实现可以使用它来执行检查。

如果dynamic_cast失败,nullptr将返回if,因此当您的演员成功并且pDerived包含有效指针时,您只会输入{{1}}的正文正确的派生对象。

在c ++中,我们通常使用 Base 类,而不是Basic类。

无论如何,一般来说,如果您的基类是多态的(包含虚函数),您可以使用dynamic_cast:

这意味着对象“a”具有“静态类型”:Base;和“动态类型”:派生。

除非您的基类具有虚函数,否则指针的指针将始终为Basic类型,并具有类型为Basic的对象的行为。实际上,即使使用虚函数,类型为Basic*的指针也始终指向类型为Basic的对象。但是动态类型''''指针可以是不同的。

如果您的基类至少有一个虚函数,那么您可以依赖:您可以使用或来获取指针的动态类型。

}

最近因为找工作,收集了很多C语言方面方面的面试题以及答案。现在新工作搞定了,决定把这些资料发出来,送给有需要的朋友,免得再象我一样到处搜寻,实在辛苦。

先发基本问题,再发编程问题..........

想成为嵌入式程序员应知道的0x10个基本问题:

1 . 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)
我在这想看到几件事情:
1) #define 语法的基本知识(例如:不能以分号结束,括号的使用,等等)
2)懂得预处理器将为你计算常数表达式的值,因此,直接写出你是如何计算一年中有多少秒而不是计算出实际的值,是更清晰而没有代价的。
3) 意识到这个表达式将使一个16位机的整型数溢出-因此要用到长整型符号L,告诉编译器这个常数是的长整型数。
4) 如果你在你的表达式中用到UL(表示无符号长整型),那么你有了一个好的起点。记住,第一印象很重要。

2 . 写一个"标准"宏MIN ,这个宏输入两个参数并返回较小的一个。
这个测试是为下面的目的而设的:
1) 标识#define在宏中应用的基本知识。这是很重要的。因为在  嵌入(inline)操作符 变为标准C的一部分之前,宏是方便产生嵌入代码的唯一方法,对于嵌入式系统来说,为了能达到要求的性能,嵌入代码经常是必须的方法。
2)三重条件操作符的知识。这个操作符存在C语言中的原因是它使得编译器能产生比if-then-else更优化的代码,了解这个用法是很重要的。
3) 懂得在宏中小心地把参数用括号括起来
4) 我也用这个问题开始讨论宏的副作用,例如:当你写下面的代码时会发生什么事?

6.C/C++编译器中虚表是如何完成的?
7.谈谈COM的线程模型。然后讨论进程内/外组件的差别。
8.谈谈IA32下的分页机制
小页(4K)两级分页模式,大页(4M)一级
9.给两个变量,如何找出一个带环单链表中是什么地方出现环的?
一个递增一,一个递增二,他们指向同一个接点时就是环出现的地方
10.在IA32中一共有多少种办法从用户态跳到内核态?
11.如果只想让程序有一个实例运行,不能运行两个。像winamp一样,只能开一个窗口,怎样实现?
用内存映射或全局原子(互斥变量)、查找窗口句柄.. 
12.如何截取键盘的响应,让所有的‘a’变成‘b’?
 13.Apartment在COM中有什么用?为什么要引入?
 14.存储过程是什么?有什么用?有什么优点?
我的理解就是一堆sql的集合,可以建立非常复杂的查询,编译运行,所以运行一次后,以后再运行速度比单独执行SQL快很多
 15.Template有什么特点?什么时候用?


网络编程中设计并发服务器,使用多进程 与 多线程 ,请问有什么区别?
1,进程:子进程是父进程的复制品。子进程获得父进程数据空间、堆和栈的复制品。
2,线程:相对与进程而言,线程是一个更加接近与执行体的概念,它可以与同进程的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。
两者都可以提高程序的并发度,提高程序运行效率和响应时间。
线程和进程在使用上各有优缺点:线程执行开销小,但不利于资源管理和保护;而进程正相反。同时,线程适合于在SMP机器上运行,而进程则可以跨机器迁移。

1、总是使用不经常改动的大型代码体。 
2、程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下,可以将所有包含文件预编译为一个预编译头。

答:函数内的sizeof有问题。根据语法,sizeof如用于数组,只能测出静态数组的大小,无法检测动态分配的或外部数组大小。函数外的str是一个静态定义的数组,因此其大小为6,函数内的str实际只是一个指向字符串的指针,没有任何额外的与数组相关的信息,因此sizeof作用于上只将其当指针看,一个指针为4个字节,因此返回4。

一个32位的机器,该机器的指针是多少位
指针是多少位只要看地址总线的位数就行了。80386以后的机子都是32的数据总线。所以指针的位数就是4个字节了。

1、写一个“标准”宏,这个宏输入两个参数并返回较小的一个。
2、嵌入式系统中经常要用到无限循环,你怎么用C编写死循环。
3、关键字static的作用是什么?
4、关键字const有什么含意?
表示常量不可以修改的变量。
5、关键字volatile有什么含意?并举出三个不同的例子?
提示编译器对象的值可能在编译器未监测到的情况下改变。

7.进程之间通信的途径
管道:以文件系统为基础
资源竞争及进程推进顺序非法
12.死锁的4个必要条件
互斥、请求保持、不可剥夺、环路
鸵鸟策略、预防策略、避免策略、检测与解除死锁
FCFS(先来先服务),优先级,时间片轮转,多级反馈
8.类的静态成员和非静态成员有何区别?
类的静态成员每个类只有一个,非静态成员每个对象一个
9.纯虚函数如何定义?使用时应注意什么?
是接口,子类必须要实现
10.数组和链表的区别
数组:数据顺序存储,固定大小
连表:数据可以随机存储,大小可动态改变

12.ISO的七层模型是什么?tcp/udp是属于哪一层?tcp/udp有何优缺点?
TCP 服务提供了数据流传输、可靠性、有效流控制、全双工操作和多路复用技术等。
与 TCP 不同, UDP 并不提供对 IP 协议的可靠机制、流控制以及错误恢复功能等。由于 UDP 比较简单, UDP 头包含很少的字节,比 TCP 负载消耗少。
tcp: 提供稳定的传输服务,有流量控制,缺点是包头大,冗余性不好

面试题: 线程与进程的区别和联系? 线程是否具有相同的堆栈? dll是否有独立的堆栈?
进程是死的,只是一些资源的集合,真正的程序执行都是线程来完成的,程序启动的时候操作系统就帮你创建了一个主线程。

每个线程有自己的堆栈。
DLL中有没有独立的堆栈,这个问题不好回答,或者说这个问题本身是否有问题。因为DLL中的代码是被某些线程所执行,只有线程拥有堆栈,如果DLL中的代码是EXE中的线程所调用,那么这个时候是不是说这个DLL没有自己独立的堆栈?如果DLL中的代码是由DLL自己创建的线程所执行,那么是不是说DLL有独立的堆栈?

以上讲的是堆栈,如果对于堆来说,每个DLL有自己的堆,所以如果是从DLL中动态分配的内存,最好是从DLL中删除,如果你从DLL中分配内存,然后在EXE中,或者另外一个DLL中删除,很有可能导致程序崩溃

第二题,c=0x10,输出的是int,最高位为1,是负数,所以它的值就是0x00的补码就是128,所以输出-128。
这两道题都是在考察二进制向int或uint转换时的最高位处理。

sizeof()和初不初始化,没有关系;

9×1024中含有1的个数为2;
512中含有1的个数为1;
256中含有1的个数为1;
15中含有1的个数为4;
故共有1的个数为8,结果为8。
用这种方法来求1的个数是很效率很高的。
不必去一个一个地移位。循环次数最少。


有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可。为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”。所谓“位域”是把一个字节中的二进位划分为几个不同的区域, 并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。

2. 由于位域不允许跨两个字节,因此位域的长度不能大于一个字节的长度,也就是说不能超过8位二进位。   

在第二个结构中,为保证num按四个字节对齐,char后必须留出3字节的空间;同时为保证整个结构的自然对齐(这里是4字节对齐),在x后还要补齐2个字节,这样就是12字节。

A.c 和B.c两个c文件中使用了两个相同名字的static变量,编译的时候会不会有问题?这两个static变量会保存到哪里(栈还是堆或者其他的)?
static的全局变量,表明这个变量仅在本模块中有意义,不会影响其他模块。
他们都放在数据区,但是编译器对他们的命名是不同的。
如果要使变量在其他模块也有意义的话,需要使用extern关键字。

第二个最后会对照是不是结构体内最大数据的倍数,不是的话,会补成是最大数据的倍数

上面是基本问题,接下来是编程问题:


本人很弱,这几个题也搞不定,特来求救:
1)读文件file1.txt的内容(例如):
2)输出和为一个给定整数的所有组合
5=1+4;5=2+3(相加的数不能重复)

兄弟,这样的题目若是做不出来实在是有些不应该, 给你一个递规反向输出字符串的例子,可谓是反序的经典例程.

你可以参考一下指针运算的细节


写一段程序,找出数组中第k大小的数,输出数所在的位置。例如{2,4,3,4,7}中,第一大的数是7,位置在4。第二大、第三大的数都是4,位置在1、3随便输出哪一个均可。函数接口为:int find_orderk(const int* narry,const int n,const int k) 
要求算法复杂度不能是O(n^2)
可以先用快速排序进行排序,其中用另外一个进行地址查找
代码如下,在VC++6.0运行通过。给分吧^-^

3.可怕的题目终于来了
象搜索的输入信息是一个字符串,统计300万输入信息中的最热门的前十条,我们每次输入的一个字符串为不超过255byte,内存使用只有1G,
请描述思想,写出算发(c语言),空间和时间复杂度,
4.国内的一些帖吧,如baidu,有几十万个主题,假设每一个主题都有上亿的跟帖子,怎么样设计这个系统速度最好,请描述思想,写出算发(c语言),空间和时间复杂度,

t.b为11,输出就是-1
3个都是有符号数int嘛。
这是位扩展问题 


这个简单的面试题目,我选输出 no(对比的应该是指针地址吧),可在VC是YES 在C是NO
lz的呢,是一个常量字符串。位于静态存储区,它在程序生命期内恒定不变。如果编译器优化的话,会有可能a和b同时指向同一个hello的。则地址相同。如果编译器没有优化,那么就是两个不同的地址,则不同谢谢!

一个单向链表,不知道头节点,一个指针指向其中的一个节点,问如何删除这个指针指向的节点?
将这个指针指向的next节点值copy到本节点,将next指向next->next,并随后删除原next指向的节点。

这种方式和编译器中得函数调用关系相关即先后入栈顺序。不过不同
编译器得处理不同。也是因为C标准中对这种方式说明为未定义,所以
各个编译器厂商都有自己得理解,所以最后产生得结果完全不同。
因为这样,所以遇见这种函数,我们首先要考虑我们得编译器会如何处理
这样得函数,其次看函数得调用方式,不同得调用方式,可能产生不同得
结果。最后是看编译器优化。


2.写一函数,实现删除字符串str1中含有的字符串str2.
第二个就是利用一个KMP匹配算法找到str2然后删除(用链表实现的话,便捷于数组)

注:PC一般采用little-endian,即高高低低,但在网络传输上,一般采用big-endian,即高低低高,华为是做网络的,所以可能考虑big-endian模式,这样输出结果可能为4

Josephu 问题为:设编号为1,2,… n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m 的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。

*转换为bool即是类型隐式转换,这种功能虽然灵活,但更多的是导致出错概率增大和维护成本升高。所以C++专门增加了bool、true、false三个关键字以提供更安全的条件表达式。
    (C)检查指针的有效性时使用((strDest==0)||(strSrc==0)),说明答题者不知道使用常量的好处。直接使用字面常量(如本例中的0)会减少程序的可维护性。0虽然简单,但程序中可能出现很多处对指针的检查,万一出现笔误,编译器不能发现,生成的程序内含逻辑错误,很难排除。而使用NULL代替0,如果出现拼写错误,编译器就会检查出来。
    (A)return new string("Invalid argument(s)");,说明答题者根本不知道返回值的用途,并且他对内存泄漏也没有警惕心。从函数中返回函数体内分配的内存是十分危险的做法,他把释放内存的义务抛给不知情的调用者,绝大多数情况下,调用者不会释放内存,这导致内存泄漏。
    (B)return 0;,说明答题者没有掌握异常机制。调用者有可能忘记检查返回值,调用者还可能无法检查返回值(见后面的链式表达式)。妄想让返回值肩负返回正确值和异常值的双重功能,其结果往往是两种功能都失效。应该以抛出异常来代替返回值,这样可以减轻调用者的负担、使错误不会被忽略、增强程序的可维护性。

两条对角线的交点,1个。

总共9个点。请用一笔将9个点连起来

}

是的,指针是一种数据类型。最纯粹的形式(主要是在这里谈论C)是void *void *可以用来传递一个内存地址(这是一个指针),但它不能被解引用。取消引用指针就是为了获取指针所指向的内存位置所包含的数据,这意味着您知道从内存中读取的数据类型。该类型决定了将读取多少内存,因为void &#34;没有&#34;void *可以设置为指向任何内存块,可以包含任何类型,因此您可以将void *转换为任何其他指针类型(例如int *),并且取而代之的是。

我们拥有的每种类型都用于存储特定的数据(值),我们使用char来存储单个字符,int来存储整数,double存储双精度小数等。除了指针之外,这些类型都不用于在内存中存储位置。因此,就像其他类型一样,指针用于存储特定的数据。所有指针的母亲都是void *

可悲的是,这个void *受到了相当的限制:您无法取消引用它,您无法将其用于指针运算(无论如何都不符合标准)。所以C为您提供了一系列派生指针类型,使生活更轻松:char *int *double *等。

更多尝试尽可能清楚地说明我的观点:

指针有自己的大小,不论它们所指的类型如何:

通过观察这两个变量的大小,最好看出区别:

上面的代码会为您提供类似&#34; 1&lt;&gt;的内容8&#34;&#34; 1&lt;&gt; 4&#34; ,具体取决于您所使用的系统。数字表示大小,以字节为单位。

指针也有自己的printf格式说明符:%p

要打印实际内存地址(指针的实际值),您必需将指针强制转换为通用void *类型。 void指针是通用指针的一种;它指针不会对它所指向的数据做出任何假设。这是malloccallocrealloc返回的通用指针,可以设置为指向任何其他类型。那么什么是char *?它是一种通用指针类型,设置为指向大小为1字节的内存块(sizeof(char))。从某种意义上说,类型指针是派生类型,但是可以这样想:char *(char *) void *my_ptr;的缩写

但实际上,什么是类型?它的要点是类型是确定如何解释内存中数据的方式。 char类型的变量表示一个字符。类型int的变量表示整数。同样适用于指针:char *x不属于char类型,类型为char *(指向char的指针)。这意味着char *x本身就是内存中的一个位置,我们可以用它来读取一个或多个char值。

我可以咆哮一会儿,但TL; TR:

是的,指针是一种数据类型(void *最纯粹的形式)。纯粹的形式是完全无法使用的(因为你无法取消引用它)。每次你决定使用指针时,C都不需要强制转换指针,而是提供了派生指针类型的便利(如char *int *等)。但实际上,它们是指针,因此它们本身就是一种数据类型。

你问了两个不同的问题。

您的标题询问“指针变量的数据类型是什么?”。答案很简单:指针变量属于某种指针类型。例如,给定:

ptr是一个指针对象,其类型为int*,这是一种指针类型。

问题正文询问“指针是否为数据类型”。通过对“数据类型”这一短语的任何合理定义,指针类型都是数据类型。

C标准从不定义短语“数据类型”,但它在几个地方使用(非正式地)。事实上,标准中的“数据类型”一词的使用都没有引用指针类型,但这并没有告诉我们什么。

标准规定所有类型都是功能类型对象类型。对象类型进一步划分为多个类别:整数类型,数组类型,结构类型,联合类型,指针类型等。指针类型可以是指向对象类型的指针或指向函数类型的指针。 (它可以是指向不完整对象类型的指针;截至2011年标准,不完整类型被归类为对象类型。)

你问题的另一个含糊之处是你使用“指针”这个词。单词“指针”本身通常指的是指针类型的对象,但它也可以引用指针类型的(例如,标准表示{ {1}}返回一个指针)。最好使用“指针”作为形容词而不是名词,所以你可以:

  • 指针对象(指针类型的对象);
  • 指针表达式(产生指针类型结果的表达式);或
  • 指针值(指针类型的值,由指针表达式产生)。

指针类型是对象类型。指针对象是一个对象;标准将对象定义为“执行环境中的数据存储区域,其内容可以表示值”。所以指针对象是数据存储的区域。

在之后,互联网上的一些随机人员写道:“指针只是一个包含地址的变量,因此可以说指针是数据类型,但它没有被定义为数据类型(根据“C编程语言”.Kernighan&amp; Ritchie)“。我不知道K&amp; R是否定义了术语“数据类型”;因为这个人没有提供具体的引用,所以如果不搜索这本书就很难说。但它是定义语言的标准,而不是K&amp; R。

我很好奇:为什么你认为指针类型不会被视为数据类型?

例如,在C标准中,没有术语数据类型的正式定义。有对象类型和函数类型。同时,指针是从对象和函数类型构造的派生类型。

因此,通常情况下,指针是数据类型,它们是从对象和函数类型构造的数据类型。

C标准中还有术语对象的定义

因此标准中存在一些矛盾。一方面,指针是对象,因为它们占用内存,内存代表它们的值。所以我们可以说指针是对象类型。另一方面,指针被视为来自对象类型的派生类型。

在我看来,如果在标准中明确写出指针是派生对象类型或派生函数类型会更好。

无论如何,你可能会勇敢地说指针是数据类型!:)

指针类型是数据类型;它们存储指针值。

没有一个单指针类型;指向int的指针与指向char的指针的类型不同,指针与指向double的指针的类型不同,指针与指向10个元素的指针的类型不同int的数组,与指向int的11元素数组的指针的类型不同。

不同的指针类型可能具有不同的大小和表示形式;唯一保证具有相同大小和表示形式的指针类型为void *char *

与指向数据的数据类型相反,您的问题可能是指“指针的数据类型”,这是人们首先要理解的。

基于此假设,然后请查看类型或。

引用的答案:“ uintptr_t是能够存储指针的无符号整数类型。通常,它与指针的大小相同。”

当然,其大小取决于平台:32位或64位。因此,请勿在不同大小的平台之间传输此变量。

请注意,要进行分配,您必须从“特定”指针类型转换为“通用”指针类型:

}

我要回帖

更多关于 指针的类型和指针指向的类型 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信