473,661 Members | 2,421 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

2d array A[][] is the same as **A, right?

I'm getting an error when using a C program that accepts **float as
arguments in my C++ code. Here the code (short):

float A[3][3] = {0,0,0,1,2,0,3, 4,0};
float W[3] = {0,0,0};
float V[3][3] = {0,0,0,0,0,0,0, 0,0};

svdcmp(A,2,2,W, V);

where the function svdcmp is void svdcmp(float **a, int m, int n, float
w[], float **v).

The compiler (MSVC++) message is:
Error C2664: 'svdcmp' : cannot convert parameter 1 from 'float [3][3]'
to 'float ** '. Types pointed to are unrelated; conversion requires
reinterpret_cas t, C-style cast or function-style cast

I'm sure I'm making a blunder somewhere but it's so long since I've
used either C or C++...! Thanks for any help.

Jul 22 '05 #1
6 1935
<sp******@yahoo .com> wrote...
I'm getting an error when using a C program that accepts **float as
arguments in my C++ code. Here the code (short):

float A[3][3] = {0,0,0,1,2,0,3, 4,0};
float W[3] = {0,0,0};
float V[3][3] = {0,0,0,0,0,0,0, 0,0};

svdcmp(A,2,2,W, V);

where the function svdcmp is void svdcmp(float **a, int m, int n, float
w[], float **v).

The compiler (MSVC++) message is:
Error C2664: 'svdcmp' : cannot convert parameter 1 from 'float [3][3]'
to 'float ** '. Types pointed to are unrelated; conversion requires
reinterpret_cas t, C-style cast or function-style cast

I'm sure I'm making a blunder somewhere but it's so long since I've
used either C or C++...! Thanks for any help.


A two-dimensional array of T (T [N][M]) is not convertible to a pointer
to a pointer to T. Period.

Do not do reinterpret_cas t either because it won't work. The types do
_not_ have the same data layout in memory. The only thing that is kind
of similar is that you can use operator[] on both, and the resulting
type allows you to use operator[] again, and the result is T&. But the
main difference is that the former type yields 'array of T' when you
use operator[], and the latter yields 'a pointer to T'.

If you have control over how 'svdcmp' is written, and you want to keep
it working for both T** and T[][], make two templates out of it. One
will have T[N][M] as the argument type, the other will have T**.

If you don't have control over 'svdcmp', and you just have to convert
your arrays into a pointer to pointers, then you'll need to create some
temporary arrays of pointers and pass them:

float A[3][3] = { ...
float V[3][3] = { ...

float *pA[] = { &A[0][0], &A[1][0], &A[2][0] };
float *pV[] = { &V[0][0], &V[1][0], &V[2][0] };

svdcmp(pA,2,2,W ,pV);

Now, without knowing more I can't vouch for the functionality being up
to your needs, but it should at least give you an idea.

V
Jul 22 '05 #2

<sp******@yahoo .com> wrote in message
news:11******** **************@ f14g2000cwb.goo glegroups.com.. .
I'm getting an error when using a C program that accepts **float as
arguments in my C++ code. Here the code (short):

float A[3][3] = {0,0,0,1,2,0,3, 4,0};
float W[3] = {0,0,0};
float V[3][3] = {0,0,0,0,0,0,0, 0,0};

svdcmp(A,2,2,W, V);

where the function svdcmp is void svdcmp(float **a, int m, int n, float
w[], float **v).

The compiler (MSVC++) message is:
Error C2664: 'svdcmp' : cannot convert parameter 1 from 'float [3][3]'
to 'float ** '. Types pointed to are unrelated; conversion requires
reinterpret_cas t, C-style cast or function-style cast

I'm sure I'm making a blunder somewhere but it's so long since I've
used either C or C++...! Thanks for any help.


No, no no 2D array is not the same as a pointer to pointer - think of it
this way, an array is a contiguous set of data, so declaring float[3][3]
will occupy 3*3*sizeof(floa t) contigous bytes of memory. Pointers can point
*anywhere* and it is likely that they will if they were allocated at
different points in the program.
Allan
Jul 22 '05 #3

Victor Bazarov wrote:
...
If you have control over how 'svdcmp' is written, and you want to keep it working for both T** and T[][], make two templates out of it. One
will have T[N][M] as the argument type, the other will have T**.
...


Ah, thanks for the tips. I do have the source code for svdcmp() - I'd
like to modify it to accept *a (much more convenient) rather than **a
or a[][]. Just a sanity check - in the code wherever it says a[j][k]
then I need to change this to a[j*N+k] (or a[k*N+j], whatever you know
what I mean :) where N is the length of that dimension.

Jul 22 '05 #4
you only need a single pointer, and then you can access it however u
like.

#define WIDTH 5
#define HEIGHT 5

#define ACCESS(ptr, x, y) (ptr[(y*WIDTH)+x])

float array[WIDTH][HEIGHT] = { .... };
float *parray = array;

ACCESS(parry, 1, 1); // same as array[1][1]

Jul 22 '05 #5
In message <7s************ ********@comcas t.com>, Victor Bazarov
<v.********@com Acast.net> writes
<sp******@yaho o.com> wrote...
I'm getting an error when using a C program that accepts **float as
arguments in my C++ code. Here the code (short):

float A[3][3] = {0,0,0,1,2,0,3, 4,0};
float W[3] = {0,0,0};
float V[3][3] = {0,0,0,0,0,0,0, 0,0};

svdcmp(A,2,2,W, V);

where the function svdcmp is void svdcmp(float **a, int m, int n, float
w[], float **v).

The compiler (MSVC++) message is:
Error C2664: 'svdcmp' : cannot convert parameter 1 from 'float [3][3]'
to 'float ** '. Types pointed to are unrelated; conversion requires
reinterpret_cas t, C-style cast or function-style cast

I'm sure I'm making a blunder somewhere but it's so long since I've
used either C or C++...! Thanks for any help.
A two-dimensional array of T (T [N][M]) is not convertible to a pointer
to a pointer to T. Period.

Do not do reinterpret_cas t either because it won't work. The types do
_not_ have the same data layout in memory. The only thing that is kind
of similar is that you can use operator[] on both, and the resulting
type allows you to use operator[] again, and the result is T&. But the
main difference is that the former type yields 'array of T' when you
use operator[], and the latter yields 'a pointer to T'.

If you have control over how 'svdcmp' is written, and you want to keep
it working for both T** and T[][], make two templates out of it. One
will have T[N][M] as the argument type, the other will have T**.


Better still, define a template "matrix traits" class which encapsulates
the concept of Matrix and provides typedefs for things like value_type
and reference, and static functions for element access and size, and
specialise that for different argument types. Then template svdcmp on
generic Matrix types deduced from its arguments. Now you can add new
Matrix representations without having to make any changes to the code of
svdcmp.

// Untested code

template <class M>
struct MatrixTraits
{
/* assume that by default this will be instanced with M as some kind of
Matrix class which already provides all the needed functionality:
*/
typedef M matrix_type;
typedef typename M::value_type value_type;
typedef typename M::reference reference;
static reference element(matrix_ type & m, size_t i, size_t j)
{ return m(i, j); }
static value_type element(matrix_ type const & m, size_t i, size_t j)
{ return m(i, j); }
static size_t width(matrix_ty pe & m) { return m.width(); }
static size_t height(matrix_t ype & m) { return m.height(); }
// etc...
};

// specialise for array of array
template <class T, size_t M, size_t N>
struct MatrixTraits <T[M][N]>
{
typedef T value_type;
typedef T & reference;
typedef T matrix_type[M][N];
static reference element(matrix_ type & m, size_t i, size_t j)
{ return m[i][j]; }
static value_type element(matrix_ type const & m, size_t i, size_t j)
{ return m[i][j]; }
static size_t width(matrix_ty pe & m) { return M; }
static size_t height(matrix_t ype & m) { return N; }
// etc...
};

typedef typename M::value_type value_type;
static value_type element(M & m, size_T i, size_t j) { return m(i, j); }
static size_t width(M & m) { return m.width(); }
static size_t height(M & m) { return m.height(); }
// etc...
};

template <class A, class V, class W>
void svdcmp(A & a, V & v, W & w)
{
typedef MatrixTraits<A> at;
typedef MatrixTraits<V> vt;
typedef MatrixTraits<W> wt;

size_t const m = at::width(a);
size_t const n = at::height(a);
for (size_t i = 0; i<m; ++i)
for (size_t j = 0; i<n; ++i)
{
at::value_type a_ij = at::element(a, i, j);
/etc.../
}
}

Or something like that.

If you don't have control over 'svdcmp', and you just have to convert
your arrays into a pointer to pointers, then you'll need to create some
temporary arrays of pointers and pass them:

float A[3][3] = { ...
float V[3][3] = { ...

float *pA[] = { &A[0][0], &A[1][0], &A[2][0] };
float *pV[] = { &V[0][0], &V[1][0], &V[2][0] };

svdcmp(pA,2,2, W,pV);

Now, without knowing more I can't vouch for the functionality being up
to your needs, but it should at least give you an idea.

V


--
Richard Herring
Jul 22 '05 #6
[reposted, less scrambled formatting :-( ]
In message <7s************ ********@comcas t.com>, Victor Bazarov
<v.********@com Acast.net> writes
<sp******@yaho o.com> wrote...
I'm getting an error when using a C program that accepts **float as
arguments in my C++ code. Here the code (short):

float A[3][3] = {0,0,0,1,2,0,3, 4,0};
float W[3] = {0,0,0};
float V[3][3] = {0,0,0,0,0,0,0, 0,0};

svdcmp(A,2,2,W, V);

where the function svdcmp is void svdcmp(float **a, int m, int n, float
w[], float **v).

The compiler (MSVC++) message is:
Error C2664: 'svdcmp' : cannot convert parameter 1 from 'float [3][3]'
to 'float ** '. Types pointed to are unrelated; conversion requires
reinterpret_cas t, C-style cast or function-style cast

I'm sure I'm making a blunder somewhere but it's so long since I've
used either C or C++...! Thanks for any help.
A two-dimensional array of T (T [N][M]) is not convertible to a pointer
to a pointer to T. Period.

Do not do reinterpret_cas t either because it won't work. The types do
_not_ have the same data layout in memory. The only thing that is kind
of similar is that you can use operator[] on both, and the resulting
type allows you to use operator[] again, and the result is T&. But the
main difference is that the former type yields 'array of T' when you
use operator[], and the latter yields 'a pointer to T'.

If you have control over how 'svdcmp' is written, and you want to keep
it working for both T** and T[][], make two templates out of it. One
will have T[N][M] as the argument type, the other will have T**.


Better still, define a template "matrix traits" class which encapsulates
the concept of Matrix and provides typedefs for things like value_type
and reference, and static functions for element access and size, and
specialise that for different argument types. Then template svdcmp on
generic Matrix types deduced from its arguments. Now you can add new
Matrix representations without having to make any changes to the code of
svdcmp.

// Untested code

template <class M>
struct MatrixTraits
{
/* assume that by default this will be instanced with M as some kind of Matrix class
which already provides all the needed functionality:
*/
typedef M matrix_type;
typedef typename M::value_type value_type;
typedef typename M::reference reference;
static reference element(matrix_ type & m, size_t i, size_t j)
{ return m(i, j); }
static value_type element(matrix_ type const & m, size_t i, size_t j)
{ return m(i, j); }
static size_t width(matrix_ty pe & m) { return m.width(); }
static size_t height(matrix_t ype & m) { return m.height(); }
// etc...
};

// specialise for array of array
template <class T, size_t M, size_t N>
struct MatrixTraits <T[M][N]>
{
typedef T value_type;
typedef T & reference;
typedef T matrix_type[M][N];
static reference element(matrix_ type & m, size_t i, size_t j)
{ return m[i][j]; }
static value_type element(matrix_ type const & m, size_t i, size_t j)
{ return m[i][j]; }
static size_t width(matrix_ty pe & m) { return M; }
static size_t height(matrix_t ype & m) { return N; }
// etc...
};
template <class A, class V, class W>
void svdcmp(A & a, V & v, W & w)
{
typedef MatrixTraits<A> at;
typedef MatrixTraits<V> vt;
typedef MatrixTraits<W> wt;

size_t const m = at::width(a);
size_t const n = at::height(a);
for (size_t i = 0; i<m; ++i)
for (size_t j = 0; i<n; ++i)
{
at::value_type a_ij = at::element(a, i, j);
/etc.../
}
}

Or something like that.
If you don't have control over 'svdcmp', and you just have to convert
your arrays into a pointer to pointers, then you'll need to create some
temporary arrays of pointers and pass them:

float A[3][3] = { ...
float V[3][3] = { ...

float *pA[] = { &A[0][0], &A[1][0], &A[2][0] };
float *pV[] = { &V[0][0], &V[1][0], &V[2][0] };

svdcmp(pA,2,2, W,pV);

Now, without knowing more I can't vouch for the functionality being up
to your needs, but it should at least give you an idea.

V


--
Richard Herring
Jul 22 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

58
10121
by: jr | last post by:
Sorry for this very dumb question, but I've clearly got a long way to go! Can someone please help me pass an array into a function. Here's a starting point. void TheMainFunc() { // Body of code... TCHAR myArray; DoStuff(myArray);
7
4139
by: Bangalore | last post by:
Hi all, Plz clarify me, on the implementation of two or three dimensional array using overloaded operator. Thanks, in advance Bangalore
20
4684
by: Pavel Stehule | last post by:
Hello, Is possible merge two arrays like array + array => array select array_append(array, array); ERROR: function array_append(integer, integer) does not exist
18
5397
by: Joshua Neuheisel | last post by:
The following code compiles with gcc 3.2.2 and Visual C++ 6: #include <stdio.h> int main() { int a = {3, 4}; printf ("%d\n", 0); return 0; }
25
2687
by: prashna | last post by:
Hi all, I have seen a piece of code(while doing code review) which declared an array of size 0.One of my friend told although it is not standard C,some compilers will support this..I am very curious to know the use of it.. The code was compiled using Diab C compiler. Also the array was declared in structure like this typedef struct someStruct
24
1946
by: Kavya | last post by:
int main (){ int a={{1,2,3},{4,5,6}}; int (*ptr)=a; /* This should be fine and give 3 as output*/ printf("%d\n",(*ptr)); ++ptr;
21
2741
by: arnuld | last post by:
int main() { const char* arr = {"bjarne", "stroustrup", "c++"}; char* parr = &arr; } this gives an error: $ g++ test.cpp test.cpp: In function 'int main()': test.cpp:4: error: cannot convert 'const char* (*)' to 'char*' in
17
7239
by: =?Utf-8?B?U2hhcm9u?= | last post by:
Hi Gurus, I need to transfer a jagged array of byte by reference to unmanaged function, The unmanaged code should changed the values of the array, and when the unmanaged function returns I need to show the array data to the end user. Can I do that? How?
18
2040
by: mdh | last post by:
>From p112 ( K&R). Given an array declared as static char arr= { { 0,1,........},{0,1,.....}}; let arr be passed as an argument to f. f( int (*arr) ) {....} It is noted that the parentheses are necessary else it would be
13
2598
by: pereges | last post by:
I've an array : {100,20, -45 -345, -2 120, 64, 99, 20, 15, 0, 1, 25} I want to split it into two different arrays such that every number <= 50 goes into left array and every number 50 goes into right array. I've done some coding but I feel this code is very inefficient: void split_array(int *a, int size_of_array) {
0
8428
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8851
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8754
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8542
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8630
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7362
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5650
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4177
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
2
1740
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.