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

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

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

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

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

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

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

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

指针也有自己的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& Ritchie)“。我不知道K& R是否定义了术语“数据类型”;因为这个人没有提供具体的引用,所以如果不搜索这本书就很难说。但它是定义语言的标准,而不是K& R。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Service?  6C/C++编译器中虚表是如何完成的?  7.谈谈COM的线程模型。然后讨论进程内/外组件的差别。  8.谈谈IA32下的分页机制。
  9.给两个变量,如何找出一个带环单链表中是什么地方出现环的?  10.在IA32中一共有多少种办法从用户态跳到内核态?  11.如果只想让程序有一个实例运行,不能运行两个。像winamp一样,只能开一个窗口,怎样实现?
  12.如何截取键盘的响应,让所有的‘a’变成‘b’  13ApartmentCOM中有什么用?为什么要引入?  14.存储过程是什么?有什么用?有什么优点?
  15Template有什么特点?什么时候用?  16.谈谈 DNA结构的特点和优点。

  微软研究院笔试题目

除了“能够让应用程序处理存储于DBMS中的数据“这一基本相似点外,两者没有太多共同之处。但是Ado使用OLE DB 接口并基于微软的COM 技术,而 接口并且基于微软的.NET 体系架构。众所周知.NET 体系不同于COM 体系, 和ADO是两种数据访问方式。ADO.net 提供对XML 的支持。

答案:都是在堆(heap)上进行动态的内存操作。用malloc函数需要指定内存分配的字节数并且不能初始化对象,new 会自动调用对象的构造函数。delete 会调用对象的destructor,而free 不会调用对象的destructor.

答案:当类中含有const、reference 成员变量;基类的构造函数都需要初始化表。

24.C++是不是类型安全的?

答案:不是。两个不同类型的指针之间可以强制转换(用reinterpret cast)。C#是类型安全的。

25.main 函数执行以前,还会执行什么代码?

答案:全局对象的构造函数会在main 函数之前执行。

26.描述内存分配方式以及它们的区别?

1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static 变量。

2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集。

3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc 或new 申请任意多少的内存,程序员自己负责在何时用free 或delete 释放内存。动态内存的生存期由程序员决定,使用非常灵活,但问题也最多。

答案:struct 的成员默认是公有的,而类的成员默认是私有的。struct 和 class 在其他方面是功能相当的。

从感情上讲,大多数的开发者感到类和结构有很大的差别。感觉上结构仅仅象一堆缺乏封装和功能的开放的内存位,而类就象活的并且可靠的社会成员,它有智能服务,有牢固的封装屏障和一个良好定义的接口。既然大多数人都这么认为,那么只有在你的类有很少的方法并且有公有数据(这种事情在良好设计的系统中是存在的!)时,你也许应该使用 struct 关键字,否则,你应该使用

28.当一个类A 中没有生命任何成员变量与成员函数,这时sizeof(A)的值是多少,如果不是零,请解释一下编译器为什么没有让它为零。(Autodesk)

答案:肯定不是零。举个反例,如果是零的话,声明一个class A[10]对象数组,而每一个对象占用的空间是零,这时就没办法区分A[0],A[1]…了。

29. 在8086 汇编下,逻辑地址和物理地址是怎样转换的?(Intel)

答案:通用寄存器给出的地址,是段内偏移地址,相应段寄存器地址*10H+通用寄存器内地址,就得到了真正要访问的地址。

30.比较C++中的4种类型转换方式?

31.分别写出BOOL,int,float,指针类型的变量a 与“零”的比较语句。

答案:1) const 常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误。

2) 有些集成化的调试工具可以对const 常量进行调试,但是不能对宏常量进行调试。

33.简述数组与指针的区别?

数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。指针可以随时指向任意类型的内存块。

(1)修改内容上的差别

p[0] = 'X’; // 编译器不能发现该错误,运行时错误

(2) 用运算符sizeof 可以计算出数组的容量(字节数)。sizeof(p),p为指针得到的是一个指针变量的字节数,而不是p 所指的内存容量。C++/C语言没有办法知道指针所指的内存容量,除非在申请内存时记住它。注意当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。

计算数组和指针的内存容量

34.类成员函数的重载、覆盖和隐藏区别?

a.成员函数被重载的特征:

(1)相同的范围(在同一个类中);

(4)virtual 关键字可有可无。

b.覆盖是指派生类函数覆盖基类函数,特征是:

(1)不同的范围(分别位于派生类与基类);

(4)基类函数必须有virtual 关键字。

c.“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:

(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。

(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)

36. 如何打印出当前源文件的文件名以及源文件的当前行号?

__FILE__和__LINE__是系统预定义宏,这种宏并不是在某个文件中定义的,而是由编译器定义的。

37. main 主函数执行完毕后,是否可能会再执行一段代码,给出说明?

38. 如何判断一段程序是由C 编译程序还是由C++编译程序编译的?

39.文件中有一组整数,要求排序后输出到另一个文件中

40. 链表题:一个链表的结点结构

(1)已知链表的头结点head,写一个函数把这个链表逆序 ( Intel)

(2)已知两个链表head1 和head2 各自有序,请把它们合并成一个链表依然有序。(保留所有结点,即便大小相同)

(3)已知两个链表head1 和head2 各自有序,请把它们合并成一个链表依然有序,这次要求用递归方法进行。 (Autodesk)

42. 写一个函数找出一个整数数组中,第二大的数 (microsoft)

43. 写一个在一个字符串(n)中寻找一个子串(m)第一个位置的函数。

KMP算法效率最好,时间复杂度是O(n+m),详见:

44. 多重继承的内存分配问题:

那么A的内存结构大致是怎么样的?

如果不考虑有虚函数、虚继承的话就相当简单;否则的话,相当复杂。

可以参考《深入探索C++对象模型》,或者:

45. 如何判断一个单链表是有环的?(注意不能用标志位,最多只能用两个额外指针)

一种O(n)的办法就是(搞两个指针,一个每次递增一步,一个每次递增两步,如果有环的话两者必然重合,反之亦然):

一、请填写BOOL , float, 指针变量 与“零值”比较的 if 语句。(10分)

提示:这里“零值”可以是0, 0.0 , FALSE或者“空指针”。例如 int 变量 n 与“零值”比较的 if 语句为:

请写出 floatx 与“零值”比较的 if 语句:

请写出 char*p 与“零值”比较的 if 语句:

3、const 有什么用途?(请至少说明两种)

4、在C++ 程序中调用被 C编译器编译后的函数,为什么要加 extern “C”声明?

5、请简述以下两个for循环的优缺点

四、有关内存的思考题(20分)

请问运行Test函数会有什么样的结果?

请问运行Test函数会有什么样的结果?

请问运行Test函数会有什么样的结果?

请问运行Test函数会有什么样的结果?

五、编写strcpy函数(10分)

已知strcpy函数的原型是

其中strDest是目的字符串,strSrc是源字符串。

(1)不调用C++/C的字符串库函数,请编写函数 strcpy

六、编写类String的构造函数、析构函数和赋值函数(25分)

已知类String的原型为:

请编写String的上述4个函数。

以上题目摘自林锐博士的《高质量C++编程指南》。大家可以去看这本书作为参考

1.是不是一个父类写了一个virtual 函数,如果子类覆盖它的函数不加virtual ,也能实现多态?
virtual修饰符会被隐形继承的。

private 也被集成,只事派生类没有访问权限而已

子类的空间里有父类的所有变量(static除外)

同一个函数只存在一个实体(inline除外)

子类覆盖它的函数不加virtual ,也能实现多态。

在子类的空间里,有父类的私有变量。私有变量不能直接访问。

内存管理是操作系统中的重要部分,两三句话恐怕谁也说不清楚吧~~
我先说个大概,希望能够抛砖引玉吧

当程序运行时需要从内存中读出这段程序的代码。代码的位置必须在物理内存中才能被运行,由于现在的操作系统中有非常多的程序运行着,内存中不能够完全放下,所以引出了虚拟内存的概念。把哪些不常用的程序片断就放入虚拟内存,当需要用到它的时候在load入主存(物理内存)中。这个就是内存管理所要做的事。内存管理还有另外一件事需要做:计算程序片段在主存中的物理位置,以便CPU调度。

内存管理有块式管理,页式管理,段式和段页式管理。现在常用段页式管理

块式管理:把主存分为一大块、一大块的,当所需的程序片断不在主存时就分配一块主存空间,把程 序片断load入主存,就算所需的程序片度只有几个字节也只能把这一块分配给它。这样会造成很大的浪费,平均浪费了50%的内存空间,但时易于管理。

页式管理:把主存分为一页一页的,每一页的空间要比一块一块的空间小很多,显然这种方法的空间利用率要比块式管理高很多。

段式管理:把主存分为一段一段的,每一段的空间又要比一页一页的空间小很多,这种方法在空间利用率上又比页式管理高很多,但是也有另外一个缺点。一个程序片断可能会被分为几十段,这样很多时间就会被浪费在计算每一段的物理地址上(计算机最耗时间的大家都知道是I/O吧)。

段页式管理:结合了段式管理和页式管理的优点。把主存分为若干页,每一页又分为若干段。好处就很明显,不用我多说了吧。

各种内存管理都有它自己的方法来计算出程序片断在主存中的物理地址,其实都很相似。

这只是一个大概而已,不足以说明内存管理的皮毛。无论哪一本操作系统书上都有详细的讲解

define 只是定义而已,在编择时只是简单代换X*X而已,并不经过算术法则的


如果const位于星号的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;
如果const位于星号的右侧,const就是修饰指针本身,即指针本身是常量。

这两个好象是一样的,此时*p可以修改,而p不能修改。

如果少了个=号,编译时就会报错,减少了出错的可能行,可以检测出是否少了=

==strcpy拷贝的结束标志是查找字符串中的/0 因此如果字符串中没有遇到/0的话 会一直复制,直到遇到/0,上面的123都因此产生越界的情况

系统会初始化static int变量为0,但该值会一直保存,所谓的不可重入...

从机制上:c是面向过程的(但c也可以编写面向对象的程序);c++是面向对象的,提供了类。但是,
c++编写面向对象的程序比c容易

从适用的方向:c适合要求代码体积小的,效率高的场合,如嵌入式;c++适合更上层的,复杂的; llinux核心大部分是c写的,因为它是系统软件,效率要求极高。

从名称上也可以看出,c++比c多了+,说明c++是c的超集;那为什么不叫c+而叫c++呢,是因为c++比
c来说扩充的东西太多了,所以就在c后面放上两个+;于是就成了c++

C语言是结构化编程语言,C++是面向对象编程语言。
C++侧重于对象而不是过程,侧重于类的设计而不是逻辑的设计。

进程间通信的方式有 共享内存, 管道 ,Socket ,消息队列 , DDE等

1. 位结构中的成员可以定义为unsigned, 也可定义为signed, 但当成员长
度为1时, 会被认为是unsigned类型。因为单个位不可能具有符号。
2. 位结构中的成员不能使用数组和指针, 但位结构变量可以是数组和指针,
如果是指针, 其成员访问方式同结构指针。
3. 位结构总长度(位数), 是各个位成员定义的位数之和, 可以超过两个字
4. 位结构成员可以与其它结构成员一起使用。
上例的结构定义了关于一个工人的信息。其中有两个位结构成员, 每个位结
构成员只有一位, 因此只占一个字节但保存了两个信息, 该字节中第一位表示工
人的状态, 第二位表示工资是否已发放。由此可见使用位结构可以节省存贮空间。

因为static使得i的值会保留上次的值。

VC6环境下得出的结果是32

  sizeof是C语言的一种单目操作符,如C语言的其他操作符++、--等。它并不是函数。sizeof操作符以字节形式给出了其操作数的存储大小。操作数可以是一个表达式或括在括号内的类型名。操作数的存储大小由操作数的类型决定。 

二、sizeof的使用方法 
  1、用于数据类型 

  数据类型必须用括号括住。如sizeof(int)。 

  变量名可以不用括号括住。如sizeof (var_name),sizeof var_name等都是正确形式。带括号的用法更普遍,大多数程序员采用这种形式。 

  注意:sizeof操作符不能用于函数类型,不完全类型或位字段。不完全类型指具有未知存储大小的数据类型,如未知存储大小的数组类型、未知内容的结构或联合类型、void类型等。 

  sizeof操作符的结果类型是size_t,它在头文件

中typedef为unsigned int类型。该类型保证能容纳实现所建立的最大对象的字节大小。 

  ANSI C正式规定字符类型为1字节。 

  3、当操作数是指针时,sizeof依赖于编译器。例如Microsoft C/C++7.0中,near类指针字节数为2,far、huge类指针字节数为4。一般Unix的指针字节数为4。 

  4、当操作数具有数组类型时,其结果是数组的总字节数。 

  5、联合类型操作数的sizeof是其最大字节成员的字节数。结构类型操作数的sizeof是这种类型对象的总字节数,包括任何垫补在内。 

  让我们看如下结构: 

  这是因为编译器在考虑对齐问题时,在结构中插入空位以控制各成员对象的地址对齐。如double类型的结构成员x要放在被4整除的地址。 

  6、如果操作数是函数中的数组形参或函数类型的形参,sizeof给出其指针的大小。 

四、sizeof与其他操作符的关系 
  sizeof的优先级为2级,比/、%等3级运算符优先级高。它可以与其他操作符一起组成表达式。如i*sizeof(int);其中i为int类型变量。 

五、sizeof的主要用途 
  1、sizeof操作符的一个主要用途是与存储分配和I/O系统那样的例程进行通信。例如: 

  2、sizeof的另一个的主要用途是计算数组中元素的个数。例如: 

  由于操作数的字节数在实现时可能出现变化,建议在涉及到操作数字节大小时用sizeof来代替常量计算。

1、 sizeof应用在结构上的情况

但是当在VC中测试上面结构的大小时,你会发现sizeof(MyStruct)为16。你知道为什么在VC中会得出这样一个结果吗?

其实,这是VC对变量存储的一个特殊处理。为了提高CPU的存储速度,VC对一些变量的起始地址做了"对齐"处理。在默认情况下,VC规定各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数。下面列出常用类型的对齐方式(vc6.0,32位系统)。

对齐方式(变量存放的起始地址相对于结构的起始地址的偏移量)


各成员变量在存放的时候根据在结构中出现的顺序依次申请空间,同时按照上面的对齐方式调整位置,空缺的字节VC会自动填充。同时VC为了确保结构的大小为结构的字节边界数(即该结构中占用最大空间的类型所占用的字节数)的倍数,所以在为最后一个成员变量申请空间后,还会根据需要自动填充空缺的字节。

下面用前面的例子来说明VC到底怎么样来存放结构的。

为上面的结构分配空间的时候,VC根据成员变量出现的顺序和对齐方式,先为第一个成员dda1分配空间,其起始地址跟结构的起始地址相同(刚好偏移量0刚好为sizeof(double)的倍数),该成员变量占用sizeof(double)=8个字节;接下来为第二个成员dda分配空间,这时下一个可以分配的地址对于结构的起始地址的偏移量为8,是sizeof(char)的倍数,所以把dda存放在偏移量为8的地方满足对齐方式,该成员变量占用sizeof(char)=1个字节;接下来为第三个成员type分配空间,这时下一个可以分配的地址对于结构的起始地址的偏移量为9,不是sizeof(int)=4的倍数,为了满足对齐方式对偏移量的约束问题,VC自动填充3个字节(这三个字节没有放什么东西),这时下一个可以分配的地址对于结构的起始地址的偏移量为12,刚好是sizeof(int)=4的倍数,所以把type存放在偏移量为12的地方,该成员变量占用sizeof(int)=4个字节;这时整个结构的成员变量已经都分配了空间,总的占用的空间大小为:8+1+3+4=16,刚好为结构的字节边界数(即结构中占用最大空间的类型所占用的字节数sizeof(double)=8)的倍数,所以没有空缺的字节需要填充。所以整个结构的大小为:sizeof(MyStruct)=8+1+3+4=16,其中有3个字节是VC自动填充的,没有放任何有意义的东西。

下面再举个例子,交换一下上面的MyStruct的成员变量的位置,使它变成下面的情况:

这个结构占用的空间为多大呢?在VC6.0环境下,可以得到sizeof(MyStruc)为24。结合上面提到的分配空间的一些原则,分析下VC怎么样为上面的结构分配空间的。(简单说明)

char dda;//偏移量为0,满足对齐方式,dda占用1个字节;

//的倍数,需要补足7个字节才能使偏移量变为8(满足对齐

//方式),因此VC自动填充7个字节,dda1存放在偏移量为8

//的地址上,它占用8个字节。

//数,满足int的对齐方式,所以不需要VC自动填充,type存

//放在偏移量为16的地址上,它占用4个字节。

};//所有成员变量都分配了空间,空间总的大小为1+7+8+4=20,不是结构

//的节边界数(即结构中占用最大空间的类型所占用的字节数sizeof

//(double)=8)的倍数,所以需要填充4个字节,以满足结构的大小为


所以该结构总的大小为:sizeof(MyStruc)为1+7+8+4+4=24。其中总的有7+4=11个字节是VC自动填充的,没有放任何有意义的东西。


VC对结构的存储的特殊处理确实提高CPU存储变量的速度,但是有时候也带来了一些麻烦,我们也屏蔽掉变量默认的对齐方式,自己可以设定变量的对齐方式。

VC中提供了#pragmapack(n)来设定变量以n字节对齐方式。n字节对齐就是说变量存放的起始地址的偏移量有两种情况:第一、如果n大于等于该变量所占用的字节数,那么偏移量必须满足默认的对齐方式,第二、如果n小于该变量的类型所占用的字节数,那么偏移量为n的倍数,不用满足默认的对齐方式。结构的总大小也有个约束条件,分下面两种情况:如果n大于所有成员变量类型所占用的字节数,那么结构的总大小必须为占用空间最大的变量占用的空间数的倍数;

否则必须为n的倍数。下面举例说明其用法。

以上结构的大小为16,下面分析其存储情况,首先为m1分配空间,其偏移量为0,满足我们自己设定的对齐方式(4字节对齐),m1占用1个字节。接着开始为m4分配空间,这时其偏移量为1,需要补足3个字节,这样使偏移量满足为n=4的倍数(因为sizeof(double)大于n),m4占用8个字节。接着为m3分配空间,这时其偏移量为12,满足为4的倍数,m3占用4个字节。这时已经为所有成员变量分配了空间,共分配了16个字节,满足为n的倍数。如果把上面的#pragma pack(4)改为#pragma pack(16),那么我们可以得到结构的大小为24。(请读者自己分析)

在VC中,sizeof有着许多的用法,而且很容易引起一些错误。下面根据sizeof后面的参数对sizeof的用法做个总结。

A. 参数为数据类型或者为一般变量。例如sizeof(int),sizeof(long)等等。这种情况要注意的是不同系统系统或者不同编译器得到的结果可能是不同的。例如int类型在16位系统中占2个字节,在32位系统中占4个字节。

B. 参数为数组或指针。下面举例说明.

//的大小,在32位系统中,当然是占4个字节。

C. 参数为结构或类。Sizeof应用在类和结构的处理情况是相同的。但有两点需要注意,第一、结构或者类中的静态成员不对结构或者类的大小产生影响,因为静态变量的存储位置与结构或者类的实例地址无关。

第二、没有成员变量的结构或类的大小为1,因为必须保证结构或类的每一

个实例在内存中都有唯一的地址。

D. 参数为其他。下面举例说明。

//数的参数在传递的时候系统处理为一个指针,所

//以sizeof(s)实际上为求指针的大小。


以上为sizeof的基本用法,在实际的使用中要注意分析VC的分配变量的分配策略,这样的话可以避免一些错误。

C.不能进行资源统计(每次只可以有一个线程对共享资源进行存取)

C.可进行资源统计(可以让一个或超过一个线程对共享资源进行存取)

第一次称,如果不相等,说明有一堆重或轻
那么把重的那堆拿下来,再放另外35个中的33
如果相等,说明假的重,如果不相等,新放上去的还是重的话,说明假的轻(不可能新放上去的轻)

第一次称,如果相等的话,这66个肯定都是真的,从这66个中取出35个来,与剩下的没称过的35个比

第3题也可以拿A(50),B(50)比一下,一样的话拿剩下的一个和真的比一下。
如果不一样,就拿其中的一堆。比如A(50)再分成两堆25比一下,一样的话就在
B(50)中,不一样就在A(50)中,结合第一次的结果就知道了。

static变量:在程序运行期内一直有效,如果定义在函数外,则在编译单元内可见,如果在函数内,在在定义的block内可见;
static函数:在编译单元内可见;

这个 sizeof是编译时运算符,编译时就确定了
可以看成和机器有关的常量。


本文主要包括二个部分,第一部分重点介绍在VC中,怎么样采用sizeof来求结构的大小,以及容易出现的问题,并给出解决问题的方法,第二部分总结出VC中sizeof的主要用法。

1、 sizeof应用在结构上的情况

但是当在VC中测试上面结构的大小时,你会发现sizeof(MyStruct)为16。你知道为什么在VC中会得出这样一个结果吗?

其实,这是VC对变量存储的一个特殊处理。为了提高CPU的存储速度,VC对一些变量的起始地址做了"对齐"处理。在默认情况下,VC规定各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数。下面列出常用类型的对齐方式(vc6.0,32位系统)。

对齐方式(变量存放的起始地址相对于结构的起始地址的偏移量)


各成员变量在存放的时候根据在结构中出现的顺序依次申请空间,同时按照上面的对齐方式调整位置,空缺的字节VC会自动填充。同时VC为了确保结构的大小为结构的字节边界数(即该结构中占用最大空间的类型所占用的字节数)的倍?/textarea>

我要回帖

更多关于 不同类型指针赋值 的文章

 

随机推荐