[英]C++ Pointers & Arrays
以下是來自C ++過程的一些代碼。 原始文件可以在這里找到; https://code.ros.org/trac/opencv/browser/trunk/opencv/modules/imgproc/src/grabcut.cpp
我的觀點是,我是C#而不是C ++程序員,所以即使我通過代碼轉換器運行它,但代碼卻沒有改變,這對我來說還是個謎。
我的問題是:a)。 'coefs'如何變成數組,以及b)。 如何填充“ c”?
給出更多的信息:'coefs'似乎不是從數組開始的,'c'似乎以某種方式神奇地獲得了至少8個項目
// fields in class called MAT:
// a distance between successive rows in bytes; includes the gap if any
size_t step;
// pointer to the data
uchar* data;
// where ptr comes from:
template<typename _Tp> _Tp* ptr(int y=0);
template<typename _Tp> inline _Tp* Mat::ptr(int y)
{
CV_DbgAssert( (unsigned)y < (unsigned)rows );
return (_Tp*)(data + step*y);
}
.....
// original question code:
static const int componentsCount = 5;
Mat model;
float* coefs;
float* mean;
float* cov;
coefs = model.ptr<float>(0);
mean = coefs + componentsCount;
cov = mean + 3*componentsCount;
for( int ci = 0; ci < componentsCount; ci++ )
if( coefs[ci] > 0 )
calcInverseCovAndDeterm( ci );
void GMM::calcInverseCovAndDeterm( int ci )
{
if( coefs[ci] > 0 )
{
float *c = cov + 9*ci;
float dtrm =
covDeterms[ci] = c[0]*(c[4]*c[8]-c[5]*c[7]) - c[1]*(c[3]*c[8]-c[5]*c[6]) + c[2]*(c[3]*c[7]-c[4]*c[6]);
當您聲明這樣的數組時:
int my_ints[10];
my_ints
是一個數組。 但是在C ++中, my_ints
也可以作為指向數組第一項的指針進行評估。 所以這樣的代碼:
int* the_first_int = my_ints;
...合法且有效,更不用說了。 您也可以像使用the_first_int
一樣使用the_first_int
,如下所示:
int the_third_int = the_first_int[2];
...這使得在C樣式的數組和指針之間反復返回幾乎是無縫的。
在代碼中,您聲明了一個指向float
的指針:
float* coefs;
(順便說一句,應該將其初始化為NULLL,但這是另一回事了),然后將其設置為某個值:
coefs = model.ptr<float>(0);
我不知道model.ptr<float>(0)
是做什么的,但是它可能分配一個數組並返回指向該數組的指針,或者返回指向已設置數組的指針。
現在,由於coefs
是float
的指針,因此您可以像在數組中那樣使用它,就像在循環中那樣:
for( int ci = 0; ci < componentsCount; ci++ )
if( coefs[ci] > 0 )
這就是為什么這樣。
coefs
如何變成陣列
在C和C ++中, p[i]
只是*(p + i)
語法糖。 當然,只有當p
恰好指向一個數組的元素並且p + i
不會超出該數組的范圍時,這種構造才有意義。 否則,您將獲得不確定的行為 。
Kos寫道:每次出現問題時,請不要只說“未定義的行為”,除非您可以使用標准的備份
好的,因為您要的是:
當將具有整數類型的表達式添加到指針或從指針中減去時,結果將具有指針操作數的類型。 如果指針操作數指向數組對象的元素,並且數組足夠大,則結果指向與原始元素偏移的元素,以使結果數組元素和原始數組元素的下標之差等於整數表達式。 換句話說,如果表達式
P
指向數組對象的第i個元素,則表達式(P)+N
(相當於N+(P)
)和(P)-N
(其中N
的值為n)到數組對象的第i + n個元素和第i-n個元素(如果存在)。 此外,如果表達式P
指向數組對象的最后一個元素,則表達式(P)+1
指向數組對象的最后一個元素之后,如果表達式Q
指向數組對象的最后一個元素之后,表達式(Q)-1
指向數組對象的最后一個元素。 如果指針操作數和結果都指向同一數組對象的元素,或者指向數組對象的最后一個元素,則求值不會產生溢出; 否則,行為是不確定的。
在C和C ++中,指針和數組是等效的。 您可以將它們視為指針或數組,具體取決於您。 指向單個變量的指針可視為1個元素的數組。
從您的代碼看來, model
是實際上包含數組的數據結構。
coefs = model.ptr<float>(0);
在這里, coefs
不會“成為”數組,但是會指向model
的現有數組,然后可以像真實數組一樣使用它。 其他變量mean
, cov
和c
也會發生相同的情況-它們都被分配了一個指向數組中特定位置的指針。 例如:
mean = coefs + componentsCount;
使mean
指向coefs
“數組”的第6 componentsCount = 5
元素(因為componentsCount = 5
)。 之后, mean
可以看作是從model
的第6個元素開始的數組。
float *c = cov + 9*ci;
c是一個指針,指向cov所指向的位置加上float大小的9倍(假設標准IEEE-754 float
4字節)。 這是指針算法。
我不確定coefs指向什么,但是我假設它已在model.ptr<float>(0);
聲明。 否則,它是無效的指針(可能為NULL)。
在C和C ++中,存在指針和數組之間區別的細目分類。 考慮以下代碼:
int A[5];
int y = *A; // The first occurrence of A is also the dereferenced value of *A
int z = A[0]; // The first occurrence of A
int *w = A; // pointer to the beginning of A
if (*w == y) {} // TRUE, dereferenced int value == int value
if (w == A) {} // TRUE, address == address
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.