??xml version="1.0" encoding="utf-8" standalone="yes"?>国产韩国精品一区二区三区久久 ,精品人妻久久久久久888,99久久国产宗和精品1上映 http://www.shnenglu.com/db123/archive/2010/01/05/104839.html董L董LTue, 05 Jan 2010 08:42:00 GMThttp://www.shnenglu.com/db123/archive/2010/01/05/104839.htmlhttp://www.shnenglu.com/db123/comments/104839.htmlhttp://www.shnenglu.com/db123/archive/2010/01/05/104839.html#Feedback0http://www.shnenglu.com/db123/comments/commentRss/104839.htmlhttp://www.shnenglu.com/db123/services/trackbacks/104839.htmlq里?br>
另外分n一段没什么用处的试代码Q?br>

#include <iostream>
#include 
<string>
#include 
<list>
#include 
<algorithm>

#include 
<vcclr.h>

using namespace System;

int main()
{
    std::list
<int> lstTest;

    std::copy( 
        std::istream_iterator
<int>(std::cin), 
        std::istream_iterator
<int>(), 
        std::back_insert_iterator
< std::list<int> >( lstTest ) 
        );

    System::Collections::Generic::List
<int>^ lstCLR = gcnew Collections::Generic::List<int>();

    
for( std::list<int>::const_iterator it = lstTest.begin();
        it 
!= lstTest.end();
        
++it )
    {
        lstCLR
->Add( *it );
    }

    printf_s( 
"-----------------------------------------\n" );

    lstCLR
->Sort();

    
for each( int i in lstCLR )
    {
        Console::WriteLine( i );
    }

    System::Collections::Generic::List
< String^ >^ lstString = gcnew Collections::Generic::List<String^>();

    
forint i =0; i < 10++i )
    {
        wchar_t sz[
12];
        swprintf_s( sz, L
"%d", i );

        lstString
->Add( gcnew String( sz ) );
    }

    std::list
<std::wstring> lstStdString;

    
for each( String^ Str in lstString )
    {
        pin_ptr
< const wchar_t > pStr = PtrToStringChars( Str );

        lstStdString.push_back( std::wstring( pStr ) );
    }

     std::copy( lstStdString.begin(), 
         lstStdString.end(), 
         std::ostream_iterator
< std::wstring, wchar_t >( std::wcout, L"\n" )
         );
     

    
return 0;
}

 q才是我l常zd的家?br>

董L 2010-01-05 16:42 发表评论
]]>
柏林噪声 perlin noisehttp://www.shnenglu.com/db123/archive/2009/09/12/96014.html董L董LSat, 12 Sep 2009 13:15:00 GMThttp://www.shnenglu.com/db123/archive/2009/09/12/96014.htmlhttp://www.shnenglu.com/db123/comments/96014.htmlhttp://www.shnenglu.com/db123/archive/2009/09/12/96014.html#Feedback0http://www.shnenglu.com/db123/comments/commentRss/96014.htmlhttp://www.shnenglu.com/db123/services/trackbacks/96014.html
柏林噪声(Perlin Noise)(?
原文链接:http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
译:azure

Many people have used random number generators in their programs to create unpredictability, make the motion and behavior of objects appear more natural, or generate textures. Random number generators certainly have their uses, but at times their output can be too harsh to appear natural. This article will present a function which has a very wide range of uses, more than I can think of, but basically anywhere where you need something to look natural in origin. What's more it's output can easily be tailored to suit your needs.
很多人在他们的程序中使用随机数生成器d造不可预,使物体的行ؓ(f)和运动表现的更加自然Q或者生成纹理。随机数生成器当然是有他们的用途的Q但是它们似乎过于苛刅R这文章将?x)展CZ个用途十分广泛的功能Q甚臛_用途比我想到的q要q泛Q其l果可以L的适合你的需求?br>
If you look at many things in nature, you will notice that they are fractal. They have various levels of detail. A common example is the outline of a mountain range. It contains large variations in height (the mountains), medium variations (hills), small variations (boulders), tiny variations (stones) . . . you could go on. Look at almost anything: the distribution of patchy grass on a field, waves in the sea, the movements of an ant, the movement of branches of a tree, patterns in marble, winds. All these phenomena exhibit the same pattern of large and small variations. The Perlin Noise function recreates this by simply adding up noisy functions at a range of different scales.
如果你观察自然界中很多事物,你会(x)注意到它们是分Ş的。它们有着很多层次l节。最q_的例子是山峰轮廓。它包含着高度上的很大变化Q山峎ͼQ中{变化(丘陵Q,的变化Q砾矻IQ微变化(矛_Q?..你可以l想象。观察几乎所有事物:(x)片状分布于田间草Qv中的波浪Q蚂蚁的q动方式Q树(wi)枝的q动Q大理石的花U,风。所有这些现象表现出了同一U的大小的变化Ş式。柏林噪声函数通过直接d一定范围内Q不同比例的噪声函数来重现这U现象?br>
To create a Perlin noise function, you will need two things, a Noise Function, and an Interpolation Function.
Z创徏一个柏林噪声函敎ͼ我们需要两个东西,一个噪声函数和一个插值函数?br>
Introduction To Noise Functions
噪声函数介绍

A noise function is essentially a seeded random number generator. It takes an integer as a parameter, and returns a random number based on that parameter. If you pass it the same parameter twice, it produces the same number twice. It is very important that it behaves in this way, otherwise the Perlin function will simply produce nonsense.
一个噪声函数基本上是一个种子随机发生器。它需要一个整C为参敎ͼ然后q回Ҏ(gu)q个参数q回一个随机数。如果你两次都传同一个参数进来,它就?x)生两ơ相同的数。这条规律非帔R要,否则柏林函数只是生成一堆垃圾?br>



Here is a graph showing an example noise function. A random value between 0 and1 is assigned to every
point on the X axis.
q里的一张图展现了噪声函数的一个例子。X轴上每个点被赋予一??之间的随机数?br>

By smoothly interpolating between the values, we can define a continuous function that takes a non-integer as a parameter. I will discuss various ways of interpolating the values later in this article.
通过在g间^滑的插|我们定义了一个带有一个非整参数的q箋函数。我们将?x)在后面的内容中讨论多种插值方?br>
Definitions
定义

Before I go any further, let me define what I mean by amplitude and frequency. If you have studied physics, you may well have come across the concept of amplitude and frequency applied to a sin wave.
当我们准备深入之前,让我定义下什么是振幅Qamplitude)和频率(frequency)。如果你学过物理Q你可能遇到q在正玄波中振幅(amlitude)和频?frequency)的概c(din)?br>

Sin Wave
The wavelength of a sin wave is the distance from one peak to another. The amplitude is the height of the wave. The frequency is defined to be 1/wavelength.
正玄?br>正玄波的波长(wavelength)是两个L峰只间的距离。振q是此L的高度。频率我们定义ؓ(f) 1/波长(wavelength)?br>

Noise Wave
In the graph of this example noise function, the red spots indicate the random values defined along the dimension of the function. In this case, the amplitude is the difference between the minimum and maximum values the function could have. The wavelength is the distance from one red spot to the next. Again frequency is defined to be 1/wavelength.
噪声?br>图中q个噪声波的例子中,U点表示定义沿着在函数维上的随机倹{在q种情况下,振幅是这个函数的最大g最值的差倹{L?wavelength)是两个红点之间的距离。同L(fng)频率(frequency)定义?/波长(wavelength).

Creating the Perlin Noise Function
创徏柏林噪声函数

Now, if you take lots of such smooth functions, with various frequencies and amplitudes, you can add them all together to create a nice noisy function. This is the Perlin Noise Function.
现在Q如果你使用很多qx函数Q分别拥有各U各L(fng)频率和振q,你可以把他们叠加在一h创徏一个漂亮的噪声函数。这个就是柏林噪声函数?br>
Take the following Noise Functions
使用以下的噪声函?br>


Add them together, and this is what you get.
他们叠加v来,你将?x)得?-)


You can see that this function has large, medium and small variations. You may even imagine that it looks a little like a mountain range. In fact many computer generated landscapes are made using this method. Of course they use 2D noise, which I shall get onto in a moment.
你能发现q个函数拥有大的Q中的和的变化。你甚至可以它已l有点像q轮廓了。事实上很多?sh)脑生成地Ş景观也是使用了这U方法,当然那用的?D的噪壎ͼ我们过一下来研究q个?br>
You can, of course, do the same in 2 dimensions.
你当然同L(fng)可以在二l下也这么做?br>
Some noise functions are created in 2D
一?D的噪声函?br>



Adding all these functions together produces a noisy pattern.
把这些函数叠加v来生的噪声样式?br>


Persistence
持箋?br>
When you're adding together these noise functions, you may wonder exactly what amplitude and frequency to use for each one. The one dimensional example above used twice the frequency and half the amplitude for each successive noise function added. This is quite common. So common in fact, that many people don't even consider using anything else. However, you can create Perlin Noise functions with different characteristics by using other frequencies and amplitudes at each step. For example, to create smooth rolling hills, you could use Perlin noise function with large amplitudes for the low frequencies , and very small amplitudes for the higher frequencies. Or you could make a flat, but very rocky plane choosing low amplitudes for low frequencies.
当你把噪声函数叠加的时候,你可能想了解每次具体使用了什么振q和频率。上面一l的例子对于每个q箋叠加的噪声函C用了两倍的频率和二分之一倍的振幅。这个太普通了Q事实上太普通,以至于很多h甚至从来都没有考虑q用其他什么。尽如此,你可以通过在每步用其他的频率和振q来创徏不同特征的柏林噪声函数。例如,Z创徏一个^滑滚动的丘陵Q你可以使用大的振幅和小的频率的柏林噪声函数Q同时小的振q和高的频率Q你可以创徏一个^圎ͼ另外要创建非帔R的q面Q应该选择的振幅和低的频率?br>
To make it simpler, and to avoid repeating the words Amplitude and Frequency all the time, a single number is used to specify the amplitude of each frequency. This value is known as Persistence. There is some ambiguity as to it's exact meaning. The term was originally coined by Mandelbrot, one of the people behind the discovery of fractals. He defined noise with a lot of high frequency as having a low persistence. My friend Matt also came up with the concept of persistence, but defined it the other way round. To be honest, I prefer Matt's definition. Sorry Mandelbrot. So our definition of persistence is this:
Z让这些更单易懂,同时Z避免重复振幅和频率这两个词,我们用一个数来表C每个频率下的振q,q个数就是持l度(Persistence)。这里的词和它的真实意义有些歧异。这个术语原本是Mandelbrot提出的,他是发现分Ş现象的h中的一个。他定义噪声拥有大量的高频率体现出低的持箋度。我的朋友Matt也想Z持箋度的概念Q但是是通过另外一U方式定义它的。诚Ӟ我更喜欢Matt的定义方式。对不v了,Mandelbrot. 所以我们这样定义持l度(persistence):
frequency = 2i
amplitude = persistencei
Where i is the ith noise function being added. To illustrate the effect of persistence on the output of the Perlin Noise, take a look at the diagrams below. They show the component noise functions that are added, the effect of the persistence value, and the resultant Perlin noise function.
i 是表C第i个被叠加的噪声函数。ؓ(f)了展C柏林函数在输出上持l度的表现效果,L(fng)下下面的图表。他们展CZ叠加的每个组成部分,持箋度的效果和最l的柏林函数?br>


Octaves
倍频

Each successive noise function you add is known as an octave. The reason for this is that each noise function is twice the frequency of the previous one. In music, octaves also have this property.
每个你所叠加的噪声函数就是一个倍频。因为每一个噪声函数是上一个的两倍频率。在音乐上,倍频也有着q项属性?br>
Exactly how many octaves you add together is entirely up to you. You may add as many or as few as you want. However, let me give you some suggestions. If you are using the perlin noise function to render an image to the screen, there will come a point when an octave has too high a frequency to be displayable. There simply may not be enough pixels on the screen to reproduce all the little details of a very high frequency noise function. Some implementations of Perlin Noise automatically add up as many noise functions they can until the limits of the screen (or other medium) are reached.
具体多少倍频你叠加在一Pq完全取决于你。你可以叠加很多也可以很。尽如此,q是让我l你一些徏议吧。如果你正用柏林噪声函数在屏幕上渲染图象的话,如果倍频频率太高会(x)使羃成一个点以至于不能显C,q就是因Z屏幕的分辨率不够。一些柏林噪声函数的实现?x)自动叠加噪声函数直到达到屏q分辨率的极限?br>
It is also wise to stop adding noise functions when their amplitude becomes too small to reproduce. Exactly when that happens depends on the level of persistence, the overall amplitude of the Perlin function and the bit resolution of your screen (or whatever).
当振q变的很的时候,也应该明智的停止再叠加噪声函数。届时当发生依靠持箋度的{Q柏林函数整体的振幅和屏q的分L率(译的烂)?br>
Making your noise functions
创造你的噪声函?

What do we look for in a noise function? Well, it's essentially a random number generator. However, unlike other random number generators you may have come across in your programs which give you a different random number every time you call them, these noise functions supply a random number calculated from one or more parameters. I.e. every time you pass the same number to the noise function, it will respond with the same number. But pass it a different number, and it will return a different number.
我们需要什么样的噪声函敎ͼ好,基本上就是一个随机数发生器。尽如此,它不像你在程序中遇到的那中每ơ调用它都返回不同的随机数的随机函数Q这些噪声函数生成一个随机数是通过一个或者多个参数计而来。例如,每次你传入一个相同的数到噪声函数里,它将每次也返回相同的随机数。但是如果传入一个不同的敎ͼ那么它又返回一个不同的敎ͼ

Well, I don't know a lot about random number generators, so I went looking for some, and here's one I found. It seems to be pretty good. It returns floating point numbers between -1.0 and1.0.
好,我对随机数生成器q不懂太多,所以我L了一些,q里我找C一个,好象很好用。它q回一个QҎ(gu)Q范围是-1.0?.0
function IntNoise(32-bit integer: x)      

x = (x<<13) ^ x;
return ( 1.0 - ( (x * (x * x * 15731 + 789221) + 1376312589) & 7fffffff) / 1073741824.0);
end IntNoise function
Now, you'll want several different random number generators, so I suggest making several copies of the above code, but use slightly different numbers. Those big scarey looking numbers are all prime numbers, so you could just use some other prime numbers of a similar size. So, to make it easy for you to find random numbers, I have written a little program to list prime numbers for you. You can give it a start number and an end number, and it will find all the primes between the two. Source code is also included, so you can easily include it into your own programs to produce a random prime number. Primes.zip
现在Q你要需要几个不同的随机数生成器Q所以我把上面的代码复制几个拯Q然后稍微修改下里面的参数。那些可怕的数字都是质数Q所以你可以Ҏ(gu)其他差不多大的质数Q让我想起了 hash key生成Q,Z让你L的找的随机数Q我已经写了一个小E序来ؓ(f)你列数。你只用输入一个v始值和一个结束|它找到所有在两g间的质数。源代码也提供,所以你可以L的包含到你自qE序中来生成随机的质?Primes.zip

Interpolation
插?

Having created your noise function, you will need to smooth out the values it returns. Again, you can choose any method you like, but some look better than others. A standard interpolation function takes three inputs, a and b, the values to be interpolated between, and x which takes a value between 0 and1. The Interpolation function returns a value between a and b based on the value x. When x equals 0, it returns a, and when x is 1, it returns b. When x is between 0 and1, it returns some value between a and b.
当创Z你的噪声函数Q你需要^滑下他的q回倹{再ơ,你可以选择M你喜Ƣ的方式Q但是有一些效果更好。一个标准的插值函数需要三个输入,a ?b, 需要在a和b之间q行插|q有x,它取D围是0?。插值函数返回a到b之间取决与x的一个倹{当x{于0,它返回a,当x{于1Ӟ它返回b。当x ??之间Ӟ它将q回a到b之间的某倹{?br>
Linear Interpolation:
U性插?br>
Looks awful, like those cheap 'plasmas' that everyone uses to generate landscapes. It's a simple algorithm though, and I suppose would be excusable if you were trying to do perlin noise in realtime.
看v来很龌龊的,像那些每个h用来生成地Ş的廉?plasmas'一P它是一个简单的法Q如果你惛_时的使用柏林噪声函数Q这U插值方式是一个选择?br>
function Linear_Interpolate(a, b, x)
  return a*(1-x) + b*x
end of function
Cosine Interpolation:
余玄插?br>
This method gives a much smother curve than Linear Interpolation. It's clearly better and worth the effort if you can afford the very slight loss in speed.
q个Ҏ(gu)U性插值生成了更^滑的曲线。它当然有着更好的效果,如果你愿意稍微损q速度的话?br>
function Cosine_Interpolate(a, b, x)
  ft = x * 3.1415927
  f = (1 - cos(ft)) * .5

  return a*(1-f) + b*f
end of function
Cubic Interpolation:
立方插|(x)

This method gives very smooth results indeed, but you pay for it in speed. To be quite honest, I'm not sure if it would give noticeably better results than Cosine Interpolation, but here it is anyway if you want it. It's a little more complicated, so pay attention. Whereas before, the interpolation functions took three inputs, the cubic interpolation takes five. Instead of just a and b, you now need v0, v1, v2 and v3, along with x as before.
q个Ҏ(gu)的确是生成了非常qx的结果,但是你付出的代h(hun)是速度。老实_(d)我不那么定它能l你比余玄插值好很多的效果,但是如果你无论如何要使用它的话,它有一点点的复杂,所以这里请注意Q之前,插值函数只需要三个参敎ͼ但是立方插值需要五个,取代了a和bQ现在你需要v0,v1,v2,v3,x和以前一样也需要?br>

q些是:(x)
v0 = a 前面一?br>v1 = a ?
v2 = b ?
v3 = b 后面一?br>

function Cubic_Interpolate(v0, v1, v2, v3,x)
  P = (v3 - v2) - (v0 - v1)
  Q = (v0 - v1) - P
  R = v2 - v0
  S = v1

  return Px3 + Qx2 + Rx + S
end of function
Smoothed Noise
qx的噪?br>
Aside from Interplolation, you can also smooth the output of the noise function to make it less random looking, and also less square in the 2D and 3D versions. Smoothing is done much as you would expect, and anyone who has written an image smoothing filter, or fire algorithm should already be familiar with the process.
Rather than simply taking the value of the noise function at a single coordinate, you can take the average of that value, and it's neighbouring values. If this is unclear, take a look at the pseudo code below.
除了插|你也可以qx噪声函数的输出来使它看v来不那么随机Q和?D?D的版本少一Ҏ(gu)块。^滑的l果和你所想的差不多,只要是写q^滑过滤或者火焰算法的人都应该相当熟?zhn)此过E。相比在一个单独的坐标上取得噪声|你可以取q_的噪声|和它临近的倹{如果你不清楚这个,可以看看下面的伪代码?br>
On the right, you can see a little diagram illustrating the difference between smoothed noise, and the same noise function without smoothing. You can see that the smooth noise is flatter, never reaching the extremes of unsmoothed noise, and the frequency appears to be roughly half. There is little point smoothing 1 dimensional noise, since these are really the only effects. Smoothing becomes more useful in 2 or three dimensions, where the effect is to reduce the squareness of the noise. Unfortunately it also reduces the contrast a little. The smoother you make it, obviously, the flatterthe noise will be.
在右面(q里看下面)Q你可以看见一个小的图展示了不同^滑函数的区别Q和同样的一个噪C未进行^滑处理。你可以看见qx函数Q从来都没有到底那个未^滑函数的极限|q且频率昑־只有大约一半。那里有点qx一l的噪声Q只有这一个效果。^滑过E在二维和三l中Q显得更有用处,那就是它减少了噪声大方块。不q的是它也降低了一点对比度。你让它^滑,q个噪声׃(x)^坦?br>


1-dimensional Smooth Noise
一l噪声函?
function Noise(x)
.
.
end function

function SmoothNoise_1D(x)

return Noise(x)/2 + Noise(x-1)/4 + Noise(x+1)/4

end function
2-dimensional Smooth Noise
二维噪声函数
function Noise(x, y)
.
.
end function

function SmoothNoise_2D(x>, y)

corners = ( Noise(x-1, y-1)+Noise(x+1, y-1)+Noise(x-1, y+1)+Noise(x+1, y+1) ) / 16
sides = ( Noise(x-1, y) +Noise(x+1, y) +Noise(x, y-1) +Noise(x, y+1) ) / 8
center = Noise(x, y) / 4

return corners + sides + center

end function
Putting it all together
把它们组合在一?br>
Now that you know all that, it's time to put together all you've learned and create a Perlin Noise function. Remember that it's just several Interpolated Noise functions added together. So Perlin Noise it just a function. You pass it one or more parameters, and it responds with a number. So, here's a simple 1 dimensional Perlin function.
既然你知道了全部q些Q现在是时候把他们l合在一起了Q你学?x)ƈ创徏一个柏林函数。记住这知识几个插值的噪声函数叠加在一赗所以柏林函数只是一个函数。你传入一个或多个参数Q然后它q回一个数l你。所以很单,一l的柏林函数是这栗?br>
The main part of the Perlin function is the loop. Each iteration of the loop adds another octave of twice the frequency. Each iteration calls a different noise function, denoted by Noisei. Now, you needn't actually write lots of noise functions, one for each octave, as the pseudo code seems to suggest. Since all the noise functions are essentially the same, except for the values of those three big prime numbers, you can keep the same code, but simply use a different set of prime numbers for each.
柏林函数重要的部分是那个循环。每ơ@环跌代叠加另一个两倍频率的倍频。每ơ跌代调用一个不同的噪声函数Q称做Noisei。当Ӟ你ƈ不需要真的写为每个倍频很多噪声函数Q伪代码中好象只是徏议这么做。既然所有的噪声函数实际上都是相同的Q除了那三个大质C同除外,你可以用同L(fng)代码Q只是每个代码改用不同的质数?br>
1-dimensional Perlin Noise Pseudo code
一l柏林噪声函C代码
function Noise1(integer x)
x = (x<<13) ^ x;
return ( 1.0 - ( (x * (x * x * 15731 + 789221) + 1376312589) & 7fffffff) / 1073741824.0);
end function

function SmoothedNoise_1(float x)
return Noise(x)/2 + Noise(x-1)/4 + Noise(x+1)/4
end function

function InterpolatedNoise_1(float x)

integer_X = int(x)
fractional_X = x - integer_X

v1 = SmoothedNoise1(integer_X)
v2 = SmoothedNoise1(integer_X + 1)

return Interpolate(v1 , v2 , fractional_X)

end function

function PerlinNoise_1D(float x)

total = 0
p = persistence
n = Number_Of_Octaves - 1

loop i from 0 to n

frequency = 2i
amplitude = pi

total = total + InterpolatedNoisei(x * frequency) * amplitude

end of i loop

return total

end function
Now it's easy to apply the same code to create a 2 or more dimensional Perlin Noise function:
现在可以L的用同L(fng)代码创徏二维或者多l的柏林噪声函数了:(x)

2-dimensional Perlin Noise Pseudocode
二维柏林噪声函数伪代?
function Noise1(integer x, integer y)
n = x + y * 57
n = (n<<13) ^ n;
return ( 1.0 - ( (n * (n * n * 15731 + 789221) + 1376312589) & 7fffffff) / 1073741824.0);
end function

function SmoothNoise_1(float x, float y)
corners = ( Noise(x-1, y-1)+Noise(x+1, y-1)+Noise(x-1, y+1)+Noise(x+1, y+1) ) / 16
sides = ( Noise(x-1, y) +Noise(x+1, y) +Noise(x, y-1) +Noise(x, y+1) ) / 8
center = Noise(x, y) / 4
return corners + sides + center
end function

function InterpolatedNoise_1(float x, float y)

integer_X = int(x)
fractional_X = x - integer_X

integer_Y = int(y)
fractional_Y = y - integer_Y

v1 = SmoothedNoise1(integer_X, integer_Y)
v2 = SmoothedNoise1(integer_X + 1, integer_Y)
v3 = SmoothedNoise1(integer_X, integer_Y + 1)
v4 = SmoothedNoise1(integer_X + 1, integer_Y + 1)

i1 = Interpolate(v1 , v2 , fractional_X)
i2 = Interpolate(v3 , v4 , fractional_X)

return Interpolate(i1 , i2 , fractional_Y)

end function

function PerlinNoise_2D(float x, float y)

total = 0
p = persistence
n = Number_Of_Octaves - 1

loop i from 0 to n

frequency = 2i
amplitude = pi

total = total + InterpolatedNoisei(x * frequency, y * frequency) * amplitude

end of i loop

return total

end function

本文来自CSDN博客Q{载请标明出处Qhttp://blog.csdn.net/anywn1314/archive/2007/10/15/1825765.aspx


董L 2009-09-12 21:15 发表评论
]]>
有h问ؓ(f)什么游戏资源要打包?/title><link>http://www.shnenglu.com/db123/archive/2009/08/28/94641.html</link><dc:creator>董L</dc:creator><author>董L</author><pubDate>Fri, 28 Aug 2009 02:33:00 GMT</pubDate><guid>http://www.shnenglu.com/db123/archive/2009/08/28/94641.html</guid><wfw:comment>http://www.shnenglu.com/db123/comments/94641.html</wfw:comment><comments>http://www.shnenglu.com/db123/archive/2009/08/28/94641.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/db123/comments/commentRss/94641.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/db123/services/trackbacks/94641.html</trackback:ping><description><![CDATA[相对而言Q对比较?yu),而且多的文g打包是很有意义的Q这也是Z么越来越多的游戏对声韌源不打包的原因?br><br>在桌面上新徏一个文本文Ӟ写入abcd四个字母Q右dQ属性,大小Q?字节Q占用空_(d)(x)4.00KB?br>q就是ؓ(f)什么要打包的原因之一?br><br>另外你可以同时处理大的打包过的文件和一大堆几万甚至几十万个文gQ速度?x)不同的。前者要快些。同时打包还可以Ҏ(gu)件进行加密、压~等{?br><br>可见打包术资源q是很有意义的,而且q有一个好处,看v来Cool!一些? <img src ="http://www.shnenglu.com/db123/aggbug/94641.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/db123/" target="_blank">董L</a> 2009-08-28 10:33 <a href="http://www.shnenglu.com/db123/archive/2009/08/28/94641.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【原创】游戏中的声韌源打?/title><link>http://www.shnenglu.com/db123/archive/2009/06/10/87371.html</link><dc:creator>董L</dc:creator><author>董L</author><pubDate>Wed, 10 Jun 2009 15:43:00 GMT</pubDate><guid>http://www.shnenglu.com/db123/archive/2009/06/10/87371.html</guid><wfw:comment>http://www.shnenglu.com/db123/comments/87371.html</wfw:comment><comments>http://www.shnenglu.com/db123/archive/2009/06/10/87371.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/db123/comments/commentRss/87371.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/db123/services/trackbacks/87371.html</trackback:ping><description><![CDATA[     摘要: 游戏中的声音资源打包 董L 介绍 在以前的游戏当中Q几乎所有的游戏都有资源打包,无论是图形资源、声x件等{。现在,来多的游戏的声音资源都公开了,通常背景音乐{采用oggQ音效采用wavQ但是图形资源绝大部分游戏还是都是打包了的。有的有加密Q有的没有?在学?fn)游戏编E的初期我就对这个东西很感兴,但是又没有h教,到网上找资料也少得可怜,所以就只好自己摸烦了。记得去q也做过cM的工作,...  <a href='http://www.shnenglu.com/db123/archive/2009/06/10/87371.html'>阅读全文</a><img src ="http://www.shnenglu.com/db123/aggbug/87371.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/db123/" target="_blank">董L</a> 2009-06-10 23:43 <a href="http://www.shnenglu.com/db123/archive/2009/06/10/87371.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【{帖】Rational Purify 使用?qing)分析实?/title><link>http://www.shnenglu.com/db123/archive/2009/05/25/85757.html</link><dc:creator>董L</dc:creator><author>董L</author><pubDate>Mon, 25 May 2009 15:36:00 GMT</pubDate><guid>http://www.shnenglu.com/db123/archive/2009/05/25/85757.html</guid><wfw:comment>http://www.shnenglu.com/db123/comments/85757.html</wfw:comment><comments>http://www.shnenglu.com/db123/archive/2009/05/25/85757.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/db123/comments/commentRss/85757.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/db123/services/trackbacks/85757.html</trackback:ping><description><![CDATA[<table cellSpacing=0 cellPadding=0 width="100%" border=0> <tbody> <tr vAlign=top> <td width="100%"> <h1>Rational Purify 使用?qing)分析实?/h1> <img class=display-img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=1></td> <td class=no-print width=192><img height=18 alt=developerWorks src="http://www.ibm.com/developerworks/i/dw.gif" width=192></td> </tr> </tbody> </table> <table cellSpacing=0 cellPadding=0 width="100%" border=0> <tbody> <tr vAlign=top> <td width=10><img height=1 alt="" src="http://www.ibm.com/i/c.gif" width=10></td> <td width="100%"> <table class=no-print cellSpacing=0 cellPadding=0 width=160 align=right border=0> <tbody> <tr> <td width=10><img height=1 alt="" src="http://www.ibm.com/i/c.gif" width=10></td> <td><!--start RESERVED FOR FUTURE USE INCLUDE FILES--><!-- this content will be automatically generated across all content areas --><!--end RESERVED FOR FUTURE USE INCLUDE FILES--></td> </tr> </tbody> </table> <p>U别Q?初</p> <p><a cmImpressionSent="1"><font color=#5c81a7>??/font></a>, IBM 中国软g开发中心Y件工E师<br></p> <p>2006 q?2 ?23 ?/p> <blockquote>本文介绍?IBM Rational Purify的基本概念和在不同操作系l中使用Purify对C/C++源程序中存在的内存问题进行勘察和分析Qƈ且提供了有关的实例以便读者在实际操作中作为参考?/blockquote><!--start RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--end RESERVED FOR FUTURE USE INCLUDE FILES--> <p><a name=N10038><span id="xptp1x3" class=atitle>?/span></a></p> <p>本文介绍了IBM Rational Purify的基本概念和在不同操作系l中使用Purify对C/C++源程序中存在的内存问题进行勘察和分析Qƈ且提供了有关的实例以便读者在实际操作中作为参考?/p> <br> <table cellSpacing=0 cellPadding=0 width="100%" border=0> <tbody> <tr> <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"><br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></td> </tr> </tbody> </table> <table class=no-print cellSpacing=0 cellPadding=0 align=right> <tbody> <tr align=right> <td><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"><br> <table cellSpacing=0 cellPadding=0 border=0> <tbody> <tr> <td vAlign=center></td> <td vAlign=top align=right><a class=fbox cmImpressionSent="1"><strong><font color=#5c81a7></font></strong></a></td> </tr> </tbody> </table> </td> </tr> </tbody> </table> <br><br> <p><a name=N10041><span id="xdtd3tj" class=atitle>1Q内存问题的原因?qing)分c?/span></a></p> <p>在C/C++E序中,有关内存使用的问题是最隑֏现和解决的。这些问题可能导致程序莫名其妙地停止、崩溃,或者不断消耗内存直臌源耗尽。由于C/C++语言本n的特质和历史原因Q程序员使用内存需要注意的事项较多Q而且语言本n也不提供cMJava的垃圾清理机制。编Eh员用一定的工具来查扑֒调试内存相关问题是十分必要的?/p> <p>ȝ说来Q与内存有关的问题可以分成两c:(x)内存讉K错误和内存用错误。内存访问错误包括错误地d内存和错误地写内存。错误地d内存可能让你的模块返回意想不到的l果Q从而导致后l的模块q行异常。错误地写内存可能导致系l崩溃。内存用方面的错误主要是指甌的内存没有正释放,从而ɽE序q行逐渐减慢Q直臛_止。这斚w的错误由于表现比较慢很难被h工察觉。程序也许运行了很久才会(x)耗净资源Q发生问题?/p> <p><a name=N1004D><span id="9ftln7x" class=smalltitle><strong><font face=Arial>1.1 内存解剖</font></strong></span></a></p> <p>一个典型的C++内存布局如下图所C:(x)</p> <br><img height=300 alt="" src="http://www.ibm.com/developerworks/cn/rational/r-cail/images/image002.jpg" width=200 border=0> <br> <p>自底向上Q内存中依次存放着只读的程序代码和数据Q全局变量和静态变量,堆中的动态申请变量和堆栈中的自动变量。自动变量就是在函数内声明的局部变量。当函数被调用时Q它们被压入栈;当函数返回时Q它们就要被弹出堆栈。堆栈的使用基本上由pȝ控制Q用户一般不?x)直接对其进行控Ӟ所以堆栈的使用q是相对安全的。动态内存是一柄双刃剑Q它可以提供E序员更灉|的内存用方法,而且有些法没有动态内存会(x)很难实现Q但是动态内存往往是内存问题存在的沃土?/p> <p><a name=N1006A><span id="79db1p3" class=smalltitle><strong><font face=Arial>1.2 内存讉K错误</font></strong></span></a></p> <p>相对用户使用的语aQ动态内存的甌一般由malloc/new来完成,释放由free/delete完成。基本的原则可以ȝ为:(x)一对一Q不L(fng)。也是说一个malloc必须对应一且唯一的freeQnew对应一且唯一的delete; malloc不能和delete, new不能和free对应。另外在C++中要注意delete和delete[]的区别。delete用来释放单元变量Qdelete[]用来释放数组{集聚变量。有兌斚w的详l信息可以参考[C++Adv]?/p> <p>我们可以内存访问错误大致分成以下几c:(x)数组界L写、访问未初始化内存、访问已l释攄内存和重复释攑ֆ存或释放非法内存?/p> <p>下面的代码集中显CZ上述问题的典型例子:(x)</p> <br> <table cellSpacing=0 cellPadding=0 width="100%" border=0> <tbody> <tr> <td class=code-outline> <pre class=displaycode>1 #include <iostream> 2 using namespace std; 3 int main(){ 4 char* str1="four"; 5 char* str2=new char[4]; //not enough space 6 char* str3=str2; 7 cout<<str2<<endl; //UMR 8 strcpy(str2,str1); //ABW 9 cout<<str2<<endl; //ABR 10 delete str2; 11 str2[0]+=2; //FMR and FMW 12 delete str3; //FFM 13 } </pre> </td> </tr> </tbody> </table> <br> <p>׃上的E序Q我们可以看刎ͼ(x)在第5行分配内存时Q忽略了字符串终止符"\0"所占空间导致了W?行的数组界写(Array Bounds WriteQ和W?行的数组界读(Array Bounds ReadQ? 在第7行,打印未赋值的str2生访问未初始化内存错误(Uninitialized Memory ReadQ?在第11行用已l释攄变量导致释攑ֆ存读和写错误(Freed Memory Read and Freed Memory Write)Q最后由于str3和str2所指的是同一片内存,W?2行又一ơ释放了已经被释攄I间 (Free Freed Memory)?/p> <p>q个包含许多错误的程序可以编译连接,而且可以在很多^Cq行。但是这些错误就像定时炸弹,?x)在?gu)配置下触发,造成不可预见的错误。这是内存错误难以发现的一个主要原因?/p> <p><a name=N10088><span id="lh7vxrx" class=smalltitle><strong><font face=Arial>1.3 内存使用错误</font></strong></span></a></p> <p>内存使用错误主要是指内存泄漏Q也是指申L(fng)动态内存没有被正确地释放,或者是没有指针可以讉Kq些内存。这些小的被人遗忘的内存块占据了一定的地址I间。当pȝ压力增大Ӟq些来多的小块将最l导致系l内存耗尽。内存用错误比内存讉K错误更加难以发现。这主要有两点原因:(x)W一Q内存用错误是"慢性病"Q它的症状可能不?x)在数、短旉的运行中体现Q第二,内存使用错误是因?不做?Q忘记释攑ֆ存)而不?做错"造成的。这L(fng)于忽略造成的错误在查局部代码时很难发现Q尤其是当系l相当复杂的时候?/p> <br> <table cellSpacing=0 cellPadding=0 width="100%" border=0> <tbody> <tr> <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"><br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></td> </tr> </tbody> </table> <table class=no-print cellSpacing=0 cellPadding=0 align=right> <tbody> <tr align=right> <td><br></td> </tr> </tbody> </table> <br><br> <p><a name=N10091><span id="7ft9ptx" class=atitle>2QPurify的原理及(qing)使用</span></a></p> <p>IBM Rational PurifyPlus是一l程序运行时的分析Y件。她包括了程序性能瓉分析软gQuantifyQ?E序覆盖面分析Y件PureCoverageQ和本文的主角:(x)E序q行错误分析软gPurify。Purify可以发现E序q行时的内存讉KQ内存泄漏和其他难以发现的问题?/p> <p>同时她也是市Z唯一支持多种q_的类似工Pq且可以和很多主开发工具集成。Purify可以查应用的每一个模块,甚至可以查出复杂的多U程或进E应用中的错误。另外她不仅可以查C/C++Q还可以对Java?NET中的内存泄漏问题l出报告?/p> <p><a name=N1009D><span id="d7vnxfl" class=smalltitle><strong><font face=Arial>2.1 Purify的原?/font></strong></span></a></p> <p>E序q行时的分析可以采用多种Ҏ(gu)。Purify使用了具有专利的目标代码插入技术(OCIQObject Code InsertionQ。她在程序的目标代码中插入了Ҏ(gu)的指令用来检查内存的状态和使用情况。这样做的好处是不需要修Ҏ(gu)代码Q只需要重新编译就可以对程序进行分析?/p> <p>对于所有程序中使用的动态内存,Purify它们按照状态进行归cR这可以׃图来说明Q来自[DEV205]Q:(x)</p> <br><img height=240 alt="" src="http://www.ibm.com/developerworks/cn/rational/r-cail/images/image003.gif" width=378 border=0> <br> <p>参见本文中以上给出的代码Q在E序W?行执行后Qstr2处于黄色状态。当在第7行进行读的时候,pȝ׃(x)报告一个访问未初始化内存错误(Uninitialized Memory ReadQ。因为只有在l色状态下Q内存才可以被合法访问?/p> <p>Z查数据越界错误(ABRQABWQ,Purifyq在每个分配的内存前后插入了U色区域。这样一来,过边界的访问指令必定落在非法区域,从而触发ABR或者ABW错误报告。这里需要指Z炏V访问未初始化内存错误UMR在某些情况下其实是合法的操作Q例如内存拷贝。所以在分析报告时可以把UMR攑ֈ最后,或者干脆从l果中o(h)除?/p> <p><a name=N100C0><span id="tnln1xz" class=smalltitle><strong><font face=Arial>2.2 Purify的?/font></strong></span></a></p> <p>q里单介l一下Purify在Windows和UNIX环境下的使用?/p> <p>在Windows中,只要q行PurifyQ填入需要分析的E序?qing)参数就可。Purify?x)自动插入检代码ƈ昄报告。报告的格式如下Q来自[DEV205]Q:(x)</p> <br><img height=349 alt="" src="http://www.ibm.com/developerworks/cn/rational/r-cail/images/image004.gif" width=735 border=0> <br> <p>蓝色的图标代表一些运行的信息Q比如开始和l束{。黄色是Purifyl出的警告。通常UMR?x)作告列出。红色则代表严重的错误。每一U相同的错误Q尤其是在@环中的,?x)被集中在一hC,q且标明发生的次数。由每个错误的详l信息,用户可以知道相应的内存地址和源代码的位|,q直接修攏V另外用戯可以讄不同的o(h)q器Q用来隐藏暂时不兛_的消息?/p> <p>在UNIXpȝ中,使用Purify需要重新编译程序。通常的做法是修改Makefile中的~译器变量。下面是用来~译本文中程序的MakefileQ?/p> <br> <table cellSpacing=0 cellPadding=0 width="100%" border=0> <tbody> <tr> <td class=code-outline> <pre class=displaycode> CC=purify gcc all: pplusdemo pplusdemo: pplusdemo.o $(CC) -o pplusdemo pplusdemo.o -lstdc++ pplusdemo.o: pplusdemo.cpp $(CC) -g -c -w pplusdemo.cpp clean: -rm pplusdemo pplusdemo.o </pre> </td> </tr> </tbody> </table> <br> <p>首先q行Purify安装目录下的purifyplus_setup.sh来设|环境变量,然后q行make重新~译E序。需要指出的是,E序必须~译成调试版本。在gcc中,也就是必M?-g"选项。在重新~译的程序运行结束后QPurify?x)打印出一个分析报告。它的格式和含义与Windowsq_大同异?/p> <p>下面是本文中的程序在Linux上Purifyq行的结果:(x)</p> <br> <table cellSpacing=0 cellPadding=0 width="100%" border=0> <tbody> <tr> <td class=code-outline> <pre class=displaycode> **** Purify instrumented ./pplusdemo (pid 30669) **** UMR: Uninitialized memory read: * This is occurring while in: strlen [rtlib.o] std::basic_ostream< char,std::char_traits< char>> & std::operator <<<std::char_traits< char>>(std::basic_ostream< char,std::char_traits< char>> &, char const *) [libstdc++.so.5] main [pplusdemo.cpp:7] __libc_start_main [libc.so.6] _start [crt1.o] * Reading 1 byte from 0x80b45e0 in the heap. * Address 0x80b45e0 is at the beginning of a malloc'd block of 4 bytes. * This block was allocated from: malloc [rtlib.o] operator new( unsigned) [libstdc++.so.5] operator new []( unsigned) [libstdc++.so.5] main [pplusdemo.cpp:5] __libc_start_main [libc.so.6] _start [crt1.o] **** Purify instrumented ./pplusdemo (pid 30669) **** ABW: Array bounds write: * This is occurring while in: strcpy [rtlib.o] main [pplusdemo.cpp:8] __libc_start_main [libc.so.6] _start [crt1.o] * Writing 5 bytes to 0x80b45e0 in the heap (1 byte at 0x80b45e4 illegal). * Address 0x80b45e0 is at the beginning of a malloc'd block of 4 bytes. * This block was allocated from: malloc [rtlib.o] operator new( unsigned) [libstdc++.so.5] operator new []( unsigned) [libstdc++.so.5] main [pplusdemo.cpp:5] __libc_start_main [libc.so.6] _start [crt1.o] **** Purify instrumented ./pplusdemo (pid 30669) **** ABR: Array bounds read: * This is occurring while in: strlen [rtlib.o] std::basic_ostream< char,std::char_traits< char>> & std::operator <<<std::char_traits< char>>(std::basic_ostream< char,std::char_traits< char>> &, char const *) [libstdc++.so.5] main [pplusdemo.cpp:9] __libc_start_main [libc.so.6] _start [crt1.o] * Reading 5 bytes from 0x80b45e0 in the heap (1 byte at 0x80b45e4 illegal). * Address 0x80b45e0 is at the beginning of a malloc'd block of 4 bytes. * This block was allocated from: malloc [rtlib.o] operator new( unsigned) [libstdc++.so.5] operator new []( unsigned) [libstdc++.so.5] main [pplusdemo.cpp:5] __libc_start_main [libc.so.6] _start [crt1.o] **** Purify instrumented ./pplusdemo (pid 30669) **** FMM: Freeing mismatched memory: * This is occurring while in: operator delete( void *) [rtlib.o] main [pplusdemo.cpp:10] __libc_start_main [libc.so.6] _start [crt1.o] * Attempting to free block at 0x80b45e0 in the heap. * Address 0x80b45e0 is at the beginning of a malloc'd block of 4 bytes. * This block was allocated from: malloc [rtlib.o] operator new( unsigned) [libstdc++.so.5] operator new []( unsigned) [libstdc++.so.5] main [pplusdemo.cpp:5] __libc_start_main [libc.so.6] _start [crt1.o] * This block of memory was obtained using an allocation routine which is not compatible with the routine by which it is being freed. **** Purify instrumented ./pplusdemo (pid 30669) **** FMR: Free memory read: * This is occurring while in: main [pplusdemo.cpp:11] __libc_start_main [libc.so.6] _start [crt1.o] * Reading 1 byte from 0x80b45e0 in the heap. * Address 0x80b45e0 is at the beginning of a freed block of 4 bytes. * This block was allocated from: malloc [rtlib.o] operator new( unsigned) [libstdc++.so.5] operator new []( unsigned) [libstdc++.so.5] main [pplusdemo.cpp:5] __libc_start_main [libc.so.6] _start [crt1.o] * There have been 0 frees since this block was freed from: free [rtlib.o] _ZdLpV [libstdc++.so.5] main [pplusdemo.cpp:10] __libc_start_main [libc.so.6] _start [crt1.o] **** Purify instrumented ./pplusdemo (pid 30669) **** FMW: Free memory write: * This is occurring while in: main [pplusdemo.cpp:11] __libc_start_main [libc.so.6] _start [crt1.o] * Writing 1 byte to 0x80b45e0 in the heap. * Address 0x80b45e0 is at the beginning of a freed block of 4 bytes. * This block was allocated from: malloc [rtlib.o] operator new( unsigned) [libstdc++.so.5] operator new []( unsigned) [libstdc++.so.5] main [pplusdemo.cpp:5] __libc_start_main [libc.so.6] _start [crt1.o] * There have been 0 frees since this block was freed from: free [rtlib.o] _ZdLpV [libstdc++.so.5] main [pplusdemo.cpp:10] __libc_start_main [libc.so.6] _start [crt1.o] **** Purify instrumented ./pplusdemo (pid 30669) **** FUM: Freeing unallocated memory: * This is occurring while in: free [rtlib.o] _ZdLpV [libstdc++.so.5] main [pplusdemo.cpp:12] __libc_start_main [libc.so.6] _start [crt1.o] * Attempting to free block at 0x80b45e0 already freed. * This block was allocated from: malloc [rtlib.o] operator new( unsigned) [libstdc++.so.5] operator new []( unsigned) [libstdc++.so.5] main [pplusdemo.cpp:5] __libc_start_main [libc.so.6] _start [crt1.o] * There have been 1 frees since this block was freed from: free [rtlib.o] _ZdLpV [libstdc++.so.5] main [pplusdemo.cpp:10] __libc_start_main [libc.so.6] _start [crt1.o] **** Purify instrumented ./pplusdemo (pid 30669) **** Current file descriptors in use: 5 FIU: file descriptor 0: <stdin> FIU: file descriptor 1: <stdout> FIU: file descriptor 2: <stderr> FIU: file descriptor 26: <reserved for Purify internal use> FIU: file descriptor 27: <reserved for Purify internal use> **** Purify instrumented ./pplusdemo (pid 30669) **** Purify: Searching for all memory leaks... Memory leaked: 0 bytes (0%); potentially leaked: 0 bytes (0%) Purify Heap Analysis (combining suppressed and unsuppressed blocks) Blocks Bytes Leaked 0 0 Potentially Leaked 0 0 In-Use 0 0 ---------------------------------------- Total Allocated 0 0 **** Purify instrumented ./pplusdemo (pid 30669) **** * Program exited with status code 0. * 7 access errors, 7 total occurrences. * 0 bytes leaked. * 0 bytes potentially leaked. * Basic memory usage (including Purify overhead): 290012 code 152928 data/bss 6816 heap (peak use) 7800 stack </pre> </td> </tr> </tbody> </table> <br> <p>我们对照E序可以发现Purify查出了程序中所有的错误。对于每个错误,她不但给Z源代码的位置q指些内存最初分配的源代码位|。这对于查找问题提供了很大帮助。对于程?2行的解释QPurify其认ؓ(f)是不匚w的内存释放(F(tun)MM: Freeing mismatched memoryQ,因ؓ(f)她认L(fng)释放方式不符合严格的规定?/p> <p>Purify在其报告和文档中使用了很多的~写Q在此一q列出,以便读者在使用时参考(来自[Purify]Q:(x)</p> <br><img height=446 alt="" src="http://www.ibm.com/developerworks/cn/rational/r-cail/images/image006.jpg" width=638 border=0> <br> <p><a name=N10112><span id="z35jjj1" class=smalltitle><strong><font face=Arial>2.3 Purify的一些特?/font></strong></span></a></p> <p>q里单介l一下Purify提供的几个特性。有兌些特性的详细信息Q请查阅文档[Purify]?/p> <ul> <li>观察点(WatchpointQ:(x)通过在程序或者调试器中调用Purify 提供的观察点函数QPurify可以报告有关被观察对象的d或其他操作? <li>与Rational其他产品的集成:(x)在Puify的用L(fng)面中可以方便地进入ClearCase和ClearQuest。Purifyq可以和PureCoverage同时使用Q对E序q行分析? <li>Purify的定Ӟ(x)无论是Purify报告中的消息Q还是界面中的元素,都可以进行一定程度的定制。另外通过修改配置文g和调用Purify APIQ用戯可以自动记录q行日志Q发送电(sh)子邮件等? <li>Purify提供的APIQؓ(f)了更好地把Purify融合到自动化试的体pMQPurify提供了一pd的公开函数。用户完全可以通过脚本的方式自动运行,记录Q和分析Purify?</li> </ul> <br> <table cellSpacing=0 cellPadding=0 width="100%" border=0> <tbody> <tr> <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"><br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></td> </tr> </tbody> </table> <table class=no-print cellSpacing=0 cellPadding=0 align=right> <tbody> <tr align=right> <td><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"><br></td> </tr> </tbody> </table> <br><br> <p><a name=N1012A><span id="hrpdvnh" class=atitle>3Qȝ</span></a></p> <p>当用C/C++q行开发时Q采用良好的一致的~程规范是防止内存问题第一道也是最重要的措施。在此前提下QIBM Rational Purify作ؓ(f)一U运行时分析软g可以很好地帮助?zhn)发现忽略的内存问题,或成Y件自动测试中的一个重要组成部分?/p> <br> <table cellSpacing=0 cellPadding=0 width="100%" border=0> <tbody> <tr> <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"><br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></td> </tr> </tbody> </table> <table class=no-print cellSpacing=0 cellPadding=0 align=right> <tbody> <tr align=right> <td><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"><br></td> </tr> </tbody> </table> <br><br> <p><a name=N10133><span id="pp7pxft" class=atitle>4Q参考资?/span></a></p> <p>[C++Adv]<br>[DEV205] Essentials of Rational PurifyPlus<br>[Purify] IBM Rational PurifyPlus for Linux and UNIX Documentation </p> <br><br> <p><a name=author><span id="vtdtvdf" class=atitle>关于作?/span></a></p> <table cellSpacing=0 cellPadding=0 width="100%" border=0> <tbody> <tr> <td colSpan=3><img height=5 alt="" src="http://www.ibm.com/i/c.gif" width="100%"></td> </tr> <tr vAlign=top align=left> <td> <p> </p> </td> <td><img height=5 alt="" src="http://www.ibm.com/i/c.gif" width=4></td> <td width="100%"> <p><strong>蔡林QIBM 中国软g开发中心Y件工E师Q?004q获得美国Baylor University计算机系士学位Q同q加入IBM 中国软g开发中心,从事Rational ClearQuest G11N的开发工作?/strong></p> </td> </tr> </tbody> </table> </td> </tr> </tbody> </table> <img src ="http://www.shnenglu.com/db123/aggbug/85757.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/db123/" target="_blank">董L</a> 2009-05-25 23:36 <a href="http://www.shnenglu.com/db123/archive/2009/05/25/85757.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【日记】最q干了点嘛?http://www.shnenglu.com/db123/archive/2009/05/24/85628.html董L董LSun, 24 May 2009 11:03:00 GMThttp://www.shnenglu.com/db123/archive/2009/05/24/85628.htmlhttp://www.shnenglu.com/db123/comments/85628.htmlhttp://www.shnenglu.com/db123/archive/2009/05/24/85628.html#Feedback0http://www.shnenglu.com/db123/comments/commentRss/85628.htmlhttp://www.shnenglu.com/db123/services/trackbacks/85628.html阅读全文

董L 2009-05-24 19:03 发表评论
]]>
【{帖】Visual C++中的日历控g使用详解http://www.shnenglu.com/db123/archive/2009/05/23/85489.html董L董LSat, 23 May 2009 00:35:00 GMThttp://www.shnenglu.com/db123/archive/2009/05/23/85489.htmlhttp://www.shnenglu.com/db123/comments/85489.htmlhttp://www.shnenglu.com/db123/archive/2009/05/23/85489.html#Feedback0http://www.shnenglu.com/db123/comments/commentRss/85489.htmlhttp://www.shnenglu.com/db123/services/trackbacks/85489.html  前言Q?/strong>

  控g在Visual C++~程学习(fn)中占据很重要的位|。笔者在国外英文|站上看Cq篇关于日历控g学习(fn)的文章,虽然内容看似单,但读完后感觉到还是学C一些东ѝ感觉到原著作者对一些不常用的日历控制的使用Ҏ(gu)写的介绍的很详细Q通俗易懂Q于qxE之中昄奇,是对日历控g?深度挖掘"Q对VC的初学者应该是很有帮助的,所以就其译q来介绍l国内读者朋友?br>
  一、有x历控件的介绍

  Win32 API提供了一个显C日期得当彩色日历控Ӟ日期的显C模式是Z控制面板中的区域性设|或者说是依赖于用户?a class=akey target=_blank>操作pȝ。具体的日历控g如下图一所C:(x)

VisualC++中的日历控g使用详解
图一、日历控件显C效?/div>

  q个常用的日历控件的标题条包含两个按钮和两个标签Q左边的按钮准许用户单击选择前一个月份,左边的标{显C当前选择的月份,双的标{显C当前日期中的年份。右边的按钮是让用户选择下一个月份。日历控件可以配|成昄多个月䆾Q下图是一具体的实例:(x)

VisualC++中的日历控g使用详解
图二、显C多个月份的日历控g

  如果要让日历控g昄多个月䆾Q按钮的个数通过前月或后月列表来增加或减。例如,如果控g正在昄4月或5月,q时用户点击了左边的按钮Q控件将昄3月或4月;如果用户点击了右边的按钮Q控件将昄5月和6月。此外,选择当前q䆾中的L一个月份,用户可以点击标题框中的月份名Q这时候将昄一个月份列表供用户来选择。具体如图所C:(x)

VisualC++中的日历控g使用详解
图三、显C月份列?/div>

  如果要更改年份,用户可以点击q䆾标签Q这时候将昄旋{按钮Q用户可以通过点击旋{按钮的上下键来更改年份,也可以?a class=akey target=_blank>键盘上的上下头来更改年份?br>
VisualC++中的日历控g使用详解
囑֛、更Ҏ(gu)历控件的q䆾


在标题条的下面,Ҏ(gu)控制面板的格式显C着星期的简写,在英语地区,每个星期的第一天通常是星期天。开发h员可以改变控件中的第一天设|?br>
  控g上,当前选择的日期有一圆圈。用户可以点?yn)L选择的日期来在控件上选择一个日期。在大部分地区,日期以数字的形式昄在一个白色背景上Q这个背景颜色乃x件上的Q何颜色可以通过E序来改变)。默认的情况下,控g昄一个椭圆围l的当前日期。用标题条按钮、月份和q䆾标签Q用户可以更Ҏ(gu)期。如果控件显C的不是当前日期Q用户可以通过点击控g底部昄今天日期的标{来使控件显CZ天的日期。(如果你是一个程序员Q可以隐藏控件底部这个显CZ日日期的标签Q?

  二、创建日历控?/strong>

  我们可以在窗口、对话框架、工h?qing)其他Q何容器窗口中创徏日历控g。日历控件对应着CmonthCalCtrlc,所以要动态创Z个日历控Ӟ需要声明一个CmonthCalCtrl变量或指向CmonthCalCtrl的指针,代码如下Q?br>
// Exercise1Dlg.h : header file
class CExercise1Dlg : public CDialog
{
 // Construction
 public:
  CExercise1Dlg(CWnd* pParent = NULL); // standard constructor
 private:
  CMonthCalCtrl *ctlCalendar;
};

  CmonthCalCtrlc象MFC中其他控件对应的cMP提供了一个Create()Ҏ(gu)用来在容器窗口中动态创建日历控Ӟ代码如下Q?br>
CExercise1Dlg::CExercise1Dlg(CWnd* pParent /*=NULL*/)
: CDialog(CExercise1Dlg::IDD, pParent)
{
 //{{AFX_DATA_INIT(CExercise1Dlg)
 //}}AFX_DATA_INIT
 // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
 ctlCalendar = new CMonthCalCtrl;
}
/////////////////////////////////////////////////////////////////////////////
// CExercise1Dlg message handlers
BOOL CExercise1Dlg::OnInitDialog()
{
 CDialog::OnInitDialog();
 // Set the icon for this dialog. The framework does this automatically
 // when the application's main window is not a dialog
 SetIcon(m_hIcon, TRUE); // Set big icon
 SetIcon(m_hIcon, FALSE); // Set small icon
 // TODO: Add extra initialization here
 ctlCalendar->Create(WS_TABSTOP | WS_CHILD | WS_VISIBLE | WS_BORDER,CPoint(20, 20), this, 0x224);
 return TRUE; // return TRUE unless you set the focus to a control
}

三、日历控件属性操?br>
  在对话框或窗口中创徏一个日历控件后Q它仅显C当前的月䆾q仅仅只能显CZ个月份,q是因ؓ(f)Q按照默认的设计Q控件的ѝ宽、高只能容纳一个月的日期,如果要显CZ个月Q就要增加控件的宽度Q同L(fng)道理Q也可以通过增加高度来显CZ个月份)?

  作ؓ(f)一个可视化对象Q日历控件可以用不同的颜色来表现背景、星期日、标题条文本、标题条背景{。作为开发h员理所当然地可以通过E序来更换这些颜Ԍ当然是要在不影响控g亲合力的情况下。改变日历控件的颜色Q需要调用CMonthCalCtrl::SetColor() Ҏ(gu)Q该Ҏ(gu)的语法是Q?br>

COLORREF SetColor(int nRegion, COLORREF ref);


  默认情况下,控g的标题条昄蓝色背景Q如果要改变它,需要向nRegion参数传递MCSC_TITLEBK|向ref参数传递你所要显C的颜色。如果更Ҏ(gu)题条上文本的颜色Q需要向nRegion参数传递MCSC_TITLETEXT倹{?br>

VisualC++中的日历控g使用详解(3)VisualC++中的日历控g使用详解(3)
图五、更Ҏ(gu)件的标题条颜?/div>


  上文说过Q在标题条的下方昄着星期日,在英语国Ӟ一个星期的W一天是星期天,如果你想更改一个星期的W一天,可以调用函数SetFirstDayOfWeek()Q它的语法是Q?br>

BOOL SetFirstDayOfWeek(int iDay, int* lpnOld = NULL);


  W一个参数必L对应的下列整数|(x)

Value Weekday
0 Monday
1 Tuesday
2 Wednesday
3 Thursday
4 Friday
5 Saturday
6 Sunday


  如果惌L(fng)日历控g的星期天中具体哪一天设|ؓ(f)W一天,可以调用函数QGetFirstDayOfWeek()Q它的语法是Q?br>

int GetFirstDayOfWeek(BOOL* pbLocal = NULL) const;


  该函数返回一个整数|它对应的含义与上个表g致?br>
  星期日的名字使用的颜色与使用SetColor()函数传递MCSC_TITLETEXT时用的颜色一_(d)在星期日的下面是一个水q_割线Q默认情况下它该是黑色的Q但q里它却与选择的日期一个颜艌Ӏ在分割U下是日期列表,默认情况下背景是Windows默认的白Ԍ如果要改变它Q需要向nRegion参数传递MCSC_MONTHBK|向ref参数传递你所要显C的颜色?br>
  表示日期的数字显C有两种颜色Q当前选择的月份中的日期以黑色表示Q如果要改变q种颜色Q可以向需要向nRegion参数传递MCSC_TRAILINGTEXT|向ref参数传递你所要显C的颜色?br>

VisualC++中的日历控g使用详解(3)VisualC++中的日历控g使用详解(3)
囑օ、更Ҏ(gu)历控件的日期昄颜色

 

分割U下的日期列表以两种颜色昄Qؓ(f)了规定当前月份中日期的颜Ԍ可以向需要向nRegion参数传递MCSC_TEXT|向ref参数传递你所要显C的颜色?br>
  日历控g?fn)惯于用两种形式来让用户了解当前的日期,一是在列表中以椭圆当前日期圈hQ另一U方式是在底部以句子的Ş式显C。在创徏控gӞ?today"属性设|ؓ(f)"NO"不昄今天的日期?br>

VisualC++中的日历控g使用详解(4)
图七、不昄"今日"标签的日历控?/div>


  如上所qͼ默认情况下控件显CZ天日期,可以通过~程使用MCS_NOTODAY来隐藏这个标{,代码如下Q?br>

BOOL CExercise1Dlg::OnInitDialog()
{
 CDialog::OnInitDialog();

 // Set the icon for this dialog. The framework does this automatically
 // when the application's main window is not a dialog
 SetIcon(m_hIcon, TRUE); // Set big icon
 SetIcon(m_hIcon, FALSE); // Set small icon

 // TODO: Add extra initialization here

 ctlCalendar->Create(WS_TABSTOP | WS_CHILD |
   WS_VISIBLE | WS_BORDER | MCS_NOTODAY,
 CPoint(20, 20), this, 0x224);

 return TRUE; // return TRUE unless you set the focus to a control
}


  我们注意刎ͼ 当前日期q被一个椭圆圈了v来,如果要将它隐藏v来,应该使用MCS_NOTODAYCIRCLEcdQ代码如下:(x)

BOOL CExercise1Dlg::OnInitDialog()
{
 CDialog::OnInitDialog();
 // Set the icon for this dialog. The framework does this automatically
 // when the application's main window is not a dialog
 SetIcon(m_hIcon, TRUE); // Set big icon
 SetIcon(m_hIcon, FALSE); // Set small icon
 // TODO: Add extra initialization here
 ctlCalendar->Create(WS_TABSTOP | WS_CHILD |
   WS_VISIBLE | WS_BORDER |
   MCS_NOTODAYCIRCLE,
 CPoint(20, 20), this, 0x224);
 return TRUE; // return TRUE unless you set the focus to a control
}


  Z获取当前日历控g中选择的日期,可以使用Ҏ(gu)QCMonthCalCtrl::GetCurSel()Q该Ҏ(gu)重蝲?个版本,它们是:(x)

BOOL GetCurSel(COleDateTime& refDateTime) const;
BOOL GetCurSel(CTime& refDateTime) const;
BOOL GetCurSel(LPSYSTEMTIME pDateTime) const;


  q里有一个例子:(x)

void CExercise1Dlg::OnRetrieveBtn()
{
 // TODO: Add your control notification handler code here
 UpdateData();
 CTime tme = this->m_dtpCurrent.GetCurrentTime();
 this->m_Result.Format("%s", tme.Format("%A, %B %d, %Y"));
 UpdateData(FALSE);
}


Z控制用户是否可以选择两个以上的日期,在创建控件时可以相应地设|多w择属性。例如,如果你想让用户在控g中选择一定范围的日期Q可以将多项选择属性设|ؓ(f)真。ؓ(f)了动态设|多日期选择Q应用MCS_MULTISELECT属性,代码如下Q?br>

BOOL CExercise1Dlg::OnInitDialog()
{
 CDialog::OnInitDialog();
 // Set the icon for this dialog. The framework does this automatically
 // when the application's main window is not a dialog
 SetIcon(m_hIcon, TRUE); // Set big icon
 SetIcon(m_hIcon, FALSE); // Set small icon

 // TODO: Add extra initialization here

 ctlCalendar->Create(WS_TABSTOP | WS_CHILD |
    WS_VISIBLE | WS_BORDER |
    MCS_NOTODAYCIRCLE | MCS_MULTISELECT,
 CPoint(20, 20), this, 0x224);

 return TRUE; // return TRUE unless you set the focus to a control
}


VisualC++中的日历控g使用详解(5)
囑օ、显C多选择日期的日历控?/div>


  通过属性设|,用户可以在日历控件中选择多个日期Q当Ӟ也可以通过动态编E来选择多个日期Q这Ӟ可以调用CMonthCalCtrl::SetSelRange()Ҏ(gu)Q它有三个不同的版本Q语法是Q?br>

BOOL SetSelRange(const COleDateTime& pMinRange, const COleDateTime& pMaxRange);
BOOL SetSelRange(const CTime& pMinRange, const CTime& pMaxRange);
BOOL SetSelRange(const LPSYSTEMTIME pMinRange, const LPSYSTEMTIME pMaxRange);


  如果惌取一个日历控件的可选择范围Q可以调用CMonthCalCtrl::GetSelRange() Ҏ(gu)?br>
  Z控制用户可选择的日期范_(d)可以调用CMonthCalCtrl::SetRange()Ҏ(gu)Q它也有三中不同的Ş式,分别是:(x)

BOOL SetRange(const COleDateTime* pMinRange, const COleDateTime* pMaxRange);
BOOL SetRange(const CTime* pMinRange, const CTime* pMaxRange);
BOOL SetRange(const LPSYSTEMTIME pMinRange, const LPSYSTEMTIME pMaxRange);


  W一个参数nMinRange是选择范围的开始日期,参数nMaxRange是可供选择的最大日期?br>

 



董L 2009-05-23 08:35 发表评论
]]>
【原创】C++字符串分?-->C库、boost.tokenizer、stlsoft.string_tokeniser讨论http://www.shnenglu.com/db123/archive/2009/05/21/83556.html董L董LThu, 21 May 2009 05:43:00 GMThttp://www.shnenglu.com/db123/archive/2009/05/21/83556.htmlhttp://www.shnenglu.com/db123/comments/83556.htmlhttp://www.shnenglu.com/db123/archive/2009/05/21/83556.html#Feedback6http://www.shnenglu.com/db123/comments/commentRss/83556.htmlhttp://www.shnenglu.com/db123/services/trackbacks/83556.html阅读全文

董L 2009-05-21 13:43 发表评论
]]>
【原创】boost.shared_ptr的相{与{h(hun)http://www.shnenglu.com/db123/archive/2009/05/18/83261.html董L董LMon, 18 May 2009 03:12:00 GMThttp://www.shnenglu.com/db123/archive/2009/05/18/83261.htmlhttp://www.shnenglu.com/db123/comments/83261.htmlhttp://www.shnenglu.com/db123/archive/2009/05/18/83261.html#Feedback0http://www.shnenglu.com/db123/comments/commentRss/83261.htmlhttp://www.shnenglu.com/db123/services/trackbacks/83261.html阅读全文

董L 2009-05-18 11:12 发表评论
]]>
【原创】boost.compressed_pair源码剖析http://www.shnenglu.com/db123/archive/2009/05/18/83260.html董L董LMon, 18 May 2009 03:09:00 GMThttp://www.shnenglu.com/db123/archive/2009/05/18/83260.htmlhttp://www.shnenglu.com/db123/comments/83260.htmlhttp://www.shnenglu.com/db123/archive/2009/05/18/83260.html#Feedback0http://www.shnenglu.com/db123/comments/commentRss/83260.htmlhttp://www.shnenglu.com/db123/services/trackbacks/83260.html阅读全文

董L 2009-05-18 11:09 发表评论
]]>
ŷպƷþþþ| þù| þۺϾɫۺŷݺ| 99þþƷѿһ| wwwþ| þþƷ| þԭavapp| 777ҹƷþav| 鶹AVһþ| ޹˾þۺ| þĻavŮ| 99þþƷձһ| þþþ| þþƷ| 99þҹɫƷվ | þĻƷһ| 97þóƷ2021| þþù޾Ʒ| Ʒþþ99| 91ƷɫۺϾþ| þˬˬav| þ㽶ۺɫһۺɫ88| ޾þһح | AAAþþþƷ| 㽶þavһ| ҹAVëƬþ| ƷһþþƷ | þþþAVƬ| þþþ| 91Ʒþþþþ91| þþƷavӰԺ| ҹƷþþþþëƬ| һAvëƬþþƷ| þþþùһ| þþþùһëƬ| þþƷһԡ| ƷŮٸAVѾþ| þþþùƷ| þþƷަvDz| Ļþ| þҹƵ|