为什么结构体在创建空间时只能用图片1的写法,2错在哪了呢,求大佬解释,谢谢(图3是结构的定义)
C语言结构体问题!!!
struct tt
{ int x;struct tt*y;}
tt是结构,他的一个成员y是个指向tt的指针,所以这样可以构造出一个tt的链表出来
p是个指向结构tt的指针
p->x 就是tt里面的x成员,p->y就是指向tt的指针
struct tt a[4]={20,a+1,15,a+2,30,a+3,17,a};
a[4]是tt数组,初始化结果是
a[0].x = 20
a[0].y = &a[1] // a+1,这是个指针的加减运算,+1表示a数组往后检索1个位置
a[1].x =15
a[1].y = &a[2]
a[2].x = 30
a[2].y = &a[3]
a[3].x = 17
a[3].y = &a[0] // a 就是a第一个元素的地址,也就是&a[0]
所以初始化结果就成为一个循环链表了,4个tt形成一个环形
看明白了吗
求助PS理论题,急啊
二、 多项选择题(每题3分,共30分)
1. 关于色域描述正确的是(ab );
A、色域是颜色的范围 B、所有的色域都是与设备相关的
C、RGB色域包括了显示设备能显示的颜色 D、Lab色域包含RGB、CMYK色域
2. 选区可以从哪些地方转化或载入(abd );
A、图层 B、通道 C、蒙版 D、路径
3. 下列工具能直接建立选区的有(ad );
A、选框工具 B、裁切工具 C、文字工具 D、文字蒙板工具
4. 下列哪种格式可以通过Acrobat软件打开(abcd );
A、PDF B、TIFF C、JPEG D、PSD
5. 可以应用下列哪些调整命令调整图象的亮度( abc);
A、色阶 B、自动色阶 C、曲线 D、色调分离
6. 下列关于专色通道的说法错误的是(bc );
A、在“专色通道选项”对话框中的“密度”(Solidity)值设得越高印刷在纸上的油墨越厚
B、 通过通道调板弹出菜单中的“合并专色通道”(Merge Spot Channel)命令可以把几个
专色通道合并为一个
C、色阶 如果要在PageMaker中单独输出专色色版,只能将Photoshop图像存为DCS2.0
格式后置入PageMaker
D、专色油墨就是除C、M、Y、K混合产生的油墨以外的其它油墨
7. 在对一幅人物图象执行了模糊、杂点等多个滤镜效果后,如果想恢复人物图象中局部,
如脸部的原来样貌,下面可行的方法(cd );
A、采用仿制图章工具
B、配合历史记录调板使用橡皮工具
C、配合历史记录调板使用历史记录画笔
D、使用菜单中的重做或后退的命令
8. 图像文件存储为下列哪个格式时,可保留专色通道?( );
A、PSD B、PDF C、TIFF D、DCS2.0
9. 关于路径叙述正确的是(acd );
A、是一种特殊的矢量图 B、可以直接被打印出来
C、路径可以转化成选区 D、可以对路径进行填充
10. 下列关于动作(Action)的描述哪些是正确的?(abc );
A、使用“动作”调板可以记录、播放、编辑或删除单个动作。还可以存储和载入动作文件
B、ImageReady 中不允许创建动作“序列”(Set),但可以在 ImageReady Actions 文件夹中
手工组织动作
C、Photoshop 和 ImageReady 附带了许多预定义的动作,不过 Photoshop 中的动作较 ImageReady 多很多。可以按原样使用这些预定义的动作,根据自己的需要对它们进行自定义,或者创建新的动作。
D、在 Photoshop 和ImageReady 中,都可以创建新动作“序列”(Set)以便更好地组织动作
三、 判断题:(请在正确的题后画“ü”,错误的题后画“×”,每题2分共20分)
1. 选区和路径都必须是封闭的。 ( x)
2. 在Photoshop中所有图层都可改变不透明度。 (r )
3. CMYK模式图像的色域比RGB模式要大。 ( x)
4. 色域是指色彩的范围,RGB颜色模式的色域是LAB>RGB>CMYK。 (r )
5. 调整图像时,用色阶调整和自动色阶调整是一样的。 ( x)
6. 画布尺寸不变,分辨率越高象素的个数越多。 ( r)
7. JPEG格式支持24bit颜色并可保留照片和大面积相同颜色
图像在亮度和色相的广泛细微的多种变化。 (x )
8. 最大的可充许的暂存磁盘的大小是100GB。 (x )
9. 按键盘上的Delete键直接将选中的路径删除。 (x )
10. PNG格式可支持24位的图像,并可生成透明背景。 ( r)
关于类和结构体的问题
本来就没有所谓原谅不原谅的,不管你对我如何说的话,我也只是看了一遍而已,我还不认为那样的话对我有伤害,既然对我没有伤害,也就没有所谓你对我道歉,我本来就信佛的,没有什么嗔与怒。所谓的七情也只是幻象而已,你产生幻象与我无关的,所以你不必道歉。
前边的问题还是有一定深度的,但补充的问题却暴露了你对的不熟悉。其中没有实例的概念,而准确的说法说是类与对象,对象是类的一个实例。如果说类实例指的就是该类实例化后的一个对象。
实例这个概念是在JS中的,因为在JS中没有类这个概念,JS只说是建立对象,而把对象“实例”后才称其为对象的一个实例。
另外你暴露的一个地方就是对象,类是引用类型是不没错,而对象却不是。对象是什么?这就比如你使用int s =5;int是一个类型,也就是说相当于一个类(基础的),而5就是对这个类的实例化,5就是5,是一个值,他的类型是int,而不是说5是一个值类型,它只能是一个值。对象与类的关系就这里,对象的类型是你定义的类,而类的类型才是引用类型。
如果这个概念一清楚,你还是说对象是一个引用类型吗?
所以我从你的补充中开始从答,先纠正一下你的概念错误,然后你问题中的部分东西就已经知道是哪里有问题了吧?换句话来说,你把类中的某些部分理解成了对象,而把对象中的某些部分理解成了类,又混在了一起说的!
堆与栈的规定并非是只由引用类型或值类型而定义的。这涉及的内容较深些了,若是了解IL时你就会知道他们真正的原因,由于篇幅较大我不准备再给你说了。再接关于栈与对象之间的关系对像说一下。
在运行时是会引入一个特别的概念,就是栈,他是在运行中的数据动态存储,如果要存储的东西是动态的(其实所谓的动态这里涉及两个概念的,编译时与运行时,运行时的是动态的,而对于对象在加载过程中固定的值是由内存中加载进来的,对于static与readonly值本身就是开辟空间时,就是实例化类时,开辟到了内存中,运行时再将值加载进来,但值却是编译态的),这些数据都在加载到栈中,之所以与汇编中不同的是,栈中的值是object,但不需要你手工打包或拆包,也就是说你存入一个int的,可以,存入一个对象还可以,string串值也可以都在这个栈中,使用时直接调用,需要什么类型就当他是什么类型,如果类型不对,那就会出错。
在IL中是这样表达实例化一个类的。
start:
创建一个栈,
存入一个int 0,
存入一个string 1,
调用一个类,使用上边两个参数做生成类(对象)的参数。
这三句相当于 类 对象名 = new 类(int,string);
具体的代码你可以查看IL代码。这两类的生成时引用了两个值,这两值用来实例化类,从而生成对象。
这是的工作原理,你可以使用VS自带的IDASM进行查看去了解IL。
也就是说他是用的值去实例化类了,但类本身这里肯定是一个引用类型了!所以有些问题你就会明白了,对象我们可以理解成即时加载到内存中,属于内存活动单元的。随便可以变化,而程序在加载中有些是不变化的。
再看一下值类型的运算,(也在IL中),它是直接将值放用入栈中,然后直接去引用了!所以这个栈有人也称工作栈或是运行栈,我们一般在评估程序时要看最大栈大小等关键性的参数。
也就是说在整个软件运行的过程中你可以看到只有这个栈是在变化的,而对于软件其他部分却是不变的。当然除了cpu的各种寄存器外——这又扯到汇编上来了。但对于IL生成汇编又是一码事,因为IL是一个中间语言,严格来说,在理解IL上也不需要去理解一些汇编的东西。只不过他的形式很象汇编而已。
通IL运行的原理,我们你会明白为什么两个不同的对象之间的数据是各自独立的。
至于堆,其实我们说的都是托管的,所以一般情况下,不需要我们看到,但是不同的值却是被分配到了不同的地方。凡是值类型都是放在了栈上,而引用类型放在堆上,判断值型是还是我说的那样,如果我们找到的值,就是值类型,如果我们找到的是指针就是引用类型,不过在C#中没有指针的概念,你可以试着用C++去理解一下。但是对于C#来说,string是比较特殊的一种指针,不是直接存放的字符,这个跟我们常说的不同,这与后来关于字符的显示是有关系的,其实纯粹是为了运行的速度。
int,double,decimal等这些都是直接存放的值,我们也假定一下:
int p = 5;
如果我引用C++的说法,*p是指针,则*p内存中存在的就是5。
而 string p = "789";则*p指针内存中不是连续的789的ACSII码,而是一个指针,指向了"789"的一个空间,那个空间才是真正的"789"的内容。
所以,我们知道class,string,object,interface还有一个托管都是引用类型,所以他们是存放在堆中。而int 之类的则是存在在栈中。你可以认为class也存放在栈中一个指针,该指针指向了堆,所以我们称引用类型存储堆中。
而对于对象来说,他包含的有值类型,有引用类型,所以对象中的一些元素有的存在堆中,有的存在栈中。对象不能说是哪种类型的。
回过头你可能对于结构又不理解了,结果呢与类是不同的,他可以直接象int p = 5这样进行赋值,也就是说,他直接放在栈中了,其实很简单,如果你使用struct时,直接在内在中开辟一下他要用到的空间。
这两种写法你能看出区别
struct p;
或者 struct p = null;
不管怎么样,先把用到的空间给开辟出来。你用到8个空间,那么这里内存必须先开出来8个空间。
class1 p;
或者
class1 p =null;
这种情况下,内存根本没有开辟空间,你用到多少?我不知道,不根本不给你开。
直接你在建立时,在堆上开辟出空间来,然后栈上的一个指针引用指向了堆,告诉你,以下你所需要的空间都是你的地盘。
这是在语言底层上去解释引用与值类型的区别的一种较好的理解方式。
呵呵,总体来说,这玩意太复杂了,不同的角度上还无法统计成一种解释。不过你这样会明白其中的原理解!
等你理解了,你才会发现,其实你根本不需要去理解。
sizeof()就结构体字节大小,字节对齐问题!如下题:
第一种情况:24
1 + (7) + 4 + 1 + (3) + 8
解释: 1 : char t
(7):因为这个结构体中最长的是double,占8位,所以补7位
4:int k
1 : char i
(3):这里涉及到一种规则,成员对齐有一个重要的条件,即每个成员按自己的方式对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里默认是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节.
这里补空要么按自身对齐需要补空,要么按最大长度补空,这也是第一个char为什么补7,这里补三,因为int占四位,不需要补,后面紧接一个char,而它们加起来已经占5为,最长8,所以补3,
8:double m;
第二种:16
4 + 1 + 1 + (2) + 8
Win32平台下的微软C编译器(cl.exe for 80×86)的对齐策略:
1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
备注:编译器在给结构体开辟空间时,首先找到结构体中最宽的基本数据类型,然后寻找内存地址能被该基本数据类型所整除的位置,作为结构体的首地址。将这个最宽的基本数据类型的大小作为上面介绍的对齐模数。
2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);
备注:为结构体的一个成员开辟空间之前,编译器首先检查预开辟空间的首地址相对于结构体首地址的偏移是否是本成员的整数倍,若是,则存放本成员,反之,则在本成员和上一个成员之间填充一定的字节,以达到整数倍的要求,也就是将预开辟空间的首地址后移几个字节。
3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要,编译器会在最末一个成员之后加上填充字节(trailing padding)。
备注:结构体总大小是包括填充字节,最后一个成员满足上面两条以外,还必须满足第三条,否则就必须在最后填充几个字节以达到本条要求。