I have this array
unsigned char bit_table_[10][100];
What is the right way to fill it with 0.
I tried
std::fill_n(bit_table_,sizeof(bit_table_),0x00);
but vc 2010 flags it as error.
On initialization:
unsigned char bit_table_[10][100] = {};
If it's a class member, you can initialize it in the constructor, like this:
MyClass::MyClass()
:bit_table_()
{}
Otherwise:
std::fill_n(*bit_table_,sizeof(bit_table_),0);
The type of bit_table_ is unsigned char [10][100], which will decay (that is, the compiler allows it to be implicitly converted to) into unsigned char (*)[100], that is, a pointer to an array of 100 unsigned chars.
std::fill_n(bit_table_, ...) is then instantiated as:
std::fill_n(unsigned char (*)[100], ...) which means it expects a value of type unsigned char [100] to initialize bit_table_ with. 0 is not convertible to that type, so the compilation fails.
Another way to think about it is that the STL functions that deal with iterators only deal with a single dimension. If you are passing in a multidimensional structure those STL functions will only deal with a single dimension.
Ultimately, you can't do this; there is no way to assign to an array type. I.e., since you can't do this:
char table[100];
char another_table[100]= { };
table= another_table;
you can't use std::fill_n on multidimensional arrays.
You can also try unsigned char bit_table_[10][100]= { 0 } to fill it with zeros.
int main()
{
unsigned char bit_table_[10][100]= { 0 };
return 0;
}
Related
how to pass array to this function ?
this is the function :
void fire(const uint8_t *const s[])
{
cout<<*s<<endl;
}
and I want to pass this array to that :
unsigned char X[10] = {255,255,255,255};
it is done by this and it works
unsigned char X[5] = {255,255,255,255};
unsigned char *pointertoX ;
pointertoX = X;
fire(&pointertoX);
why I need *pointertoX ?
is there any other way for do this ?
whole code :
#include <iostream>
using namespace std;
void fire(const uint8_t *const s[])
{
cout<<*s<<endl;
}
int main() {
unsigned char X[10] = {255,255,255,255};
unsigned char *pointertoX ;
pointertoX = X;
fire(&pointertoX);
return 0;
}
note : I'm trying to pass bitmap to ffmpeg "sws_scale" ..
https://ffmpeg.org/doxygen/4.1/group__libsws.html#gae531c9754c9205d90ad6800015046d74
this is the function :
void fire(const uint8_t *const s[])
That function accepts a pointer to a const pointer to a const uint8_t.
and I want to pass this array to that :
unsigned char X[10] = {255,255,255,255};
You cannot.
In order to pass an array into a function that accepts a pointer, the function would have to accept a pointer to element type of that array (after other implicit conversions such as pointer from to non-const into pointer to const). The element of that array is unsigned char, while the function accepts a pointer to a const pointer to a const uint8_t.
why I need *pointertoX ?
Because the function accepts a pointer to a const pointer to a const uint8_t, and &pointertoX is a pointer to a pointer to an unsigned char. Given that uint8_t is an alias of unsigned char, &pointertoX is implicitly convertible to the function parameter.
note : I'm trying to pass bitmap to ffmpeg "sws_scale" ..
Read the documentation carefully:
srcSlice the array containing the pointers to the planes of the source slice
dst the array containing the pointers to the planes of the destination image
You're trying to pass an array of characters into a function that expects an array of pointers.
P.S. The behaviour of the program is undefined because *s does not point to a null terminated string, but you insert it into a character stream which has such requirement.
I want to ask if there is difference between this two array passing method:
unsigned char array[100];
function(array);
Where:
library.cpp
uint8_t LibraryClass::function(unsigned char array[]) { }
library.h
uint8_t function(unsigned char array[]);
And this:
unsigned char array[100];
function(array);
Where:
library.cpp
uint8_t LibraryClass::function(const unsigned char* array) { }
library.h
uint8_t function(const unsigned char* array);
My questions is:
There is difference between this to methods?
Additional question:
My MCU need to do additional operation in method 1 instead of method 2?
There is additional const in method 2, why is used? It is safety to use const when using pointers?
unsigned char array[] is just syntactic sugar for unsigned char *array in a function declaration. They're literally identical.
The const means that function guarantees not to modify the contents of array. The first example makes no such guarantee to the caller.
Normally in c/c++ unsigned char array[] is unsigned char* array which consists of contiguous memory.
Whenever an array is passed to a function it is treated as pointer(*) denoting the base address.
Mentioning const- (const unsigned char* array) denotes its value will not change.
I have a bit of a problem with my constructor.
In my header file I declare:
char short_name_[2];
and other variables
In my constructor:
Territory(std::string name, char short_name[2], Player* owner, char units);
void setShortName(char* short_name);
inline const char (&getShortName() const)[2] { return short_name_; }
In my cpp file:
Territory::Territory(std::string name, char short_name[2], Player* owner,
char units) : name_(name), short_name_(short_name),
owner_(owner), units_(units)
{ }
My error:
Territory.cpp: In constructor ‘Territory::Territory(std::string,
char*, Player*, char)’: Territory.cpp:15:33: error: incompatible types
in assignment of ‘char*’ to ‘char [2]’
I already figured out that char[2] <=> char* but I'm not sure how to handle this about my constructor and get/setters.
Raw arrays in C++ are kind of annoying and fraught with peril. This is why unless you have a very good reason to you should use std::vector or std::array.
First off, as others have said, char[2] is not the same as char*, or at least not usually. char[2] is a size 2 array of char and char* is a pointer to a char. They often get confused because arrays will decay to a pointer to the first element whenever they need to. So this works:
char foo[2];
char* bar = foo;
But the reverse does not:
const char* bar = "hello";
const char foo[6] = bar; // ERROR
Adding to the confusion, when declaring function parameters, char[] is equivalent to char*. So in your constructor the parameter char short_name[2] is really char* short_name.
Another quirk of arrays is that they cannot be copied like other types (this is one explanation for why arrays in function parameters are treated as pointers). So for example I can not do something like this:
char foo[2] = {'a', 'b'};
char bar[2] = foo;
Instead I have to iterate over the elements of foo and copy them into bar, or use some function which does that for me such as std::copy:
char foo[2] = {'a', 'b'};
char bar[2];
// std::begin and std::end are only available in C++11
std::copy(std::begin(foo), std::end(foo), std::begin(bar));
So in your constructor you have to manually copy the elements of short_name into short_name_:
Territory::Territory(std::string name, char* short_name, Player* owner,
char units) : name_(name), owner_(owner), units_(units)
{
// Note that std::begin and std::end can *not* be used on pointers.
std::copy(short_name, short_name + 2, std::begin(short_name));
}
As you can see this is all very annoying, so unless you have a very good reason you just should use std::vector instead of raw arrays (or in this case probably std::string).
When a function wants an array as argument, it gets a pointer to the first element of an array instead. This pointer cannot be used to initialize an array, because it's a pointer, not an array.
You can write functions that accept references to arrays as arguments:
void i_dont_accept_pointers(const char (array&)[2]) {}
The problem here is, that this array reference cannot be used to initialize another array.
class Foo {
char vars[2];
Foo(const char (args&)[2])
: vars(args) // This will not work
{}
};
C++ 11 introduced std::array to eliminiate this and other problems of arrays. In older versions, you will have to iterate through the array elements and copy them individually or use std::copy.
C++ as C holds most of the rules of C.
In case of C, always use char* to pass array because that how C looks at it. Even sizeof (short_name_) will be 8 or 4 when passed to function.
Now, you have a space of 2 bytes in variable short_name_
Constructor allocated memory for two bytes in short_name_ and you need to copy the bytes into that or use a char * pointer and assume it's size if 2.
Chapter 9 from Expert C Programming: Deep C Secrets is good read to understand it.
For simplicity this could be C style code.
#include <stdio.h>
#include <iostream>
using namespace std;
class Territory {
private:
string s;
char c[2];
public:
Territory(std::string a, char b[2] /*visualize as char *b*/) {
s = a;
c[0] = b[0]; //or use strcpy
c[1] = b[1];
}
void PrintMe() {
printf ("As string %s as char %c or %s\n",this->s.c_str(), c[0],c);
}
};
main () {
Territory a("hello", "h");
a.PrintMe();
}
I'm trying to use a Union in a Windows Forms application in C++. My code goes like this:
union mytypes1_t {
unsigned long mylong;
char mychar;
} mytypes1;
After the includes at the top of my Form1.h file, and:
for (int num = 0;num<3;num++) {
mytypes1.mychar[0]='a';
}
When a button is clicked.
I get the error ... "subscript requires array or pointer type"
Where am I going wrong?
Your mychar is not an array or pointer you could instead declare it like so:
union mytypes1_t {
unsigned long mylong;
char mychar[4];
} mytypes1;
char mychar; is not an array nor pointer type.
for (int num = 0;num<3;num++) { mytypes1.mychar[0]='a'; }
^^^
and the loop makes no sense.
Well, like the error says, you can only use subscript [] with an array or a pointer type.
mytypes1.mychar is of type char - That is not an array, nor is it a pointer.
An array would be something like this: char mychar[12];
A pointer would be something like this: char* mychar; - but if you use the pointer, be sure to make it point to something first (such as a heap-allocated array).
A char is a single character. When we do char* or char[] it allows us to store multiple chars on the the computer. This also means, you cannot access non-pointer chars like an array as you attempted to do (since arrays are essentially convient form of pointers when it comes to storing stuff).
You can change your code to the following:
union mytypes1_t {
unsigned long mylong;
char *mychar;
} mytypes1;
The following compiles in Visual Studio but fails to compile under g++.
int main()
{
int a = unsigned char('0');
return 0;
}
Is unsigned char() a valid way to cast in C++?
No, it's not legal.
A function-style explicit type conversion requires a simple-type-specifier, followed by a parenthesized expression-list. (§5.2.3) unsigned char is not a simple-type-specifier; this is related to a question brought up by James.
Obviously, if unsigned char was a simple-type-specifier, it would be legal. A work-around is to use std::identity:
template <typename T>
struct identity
{
typedef T type;
};
And then:
int a = std::identity<unsigned char>::type('0');
std::identity<unsigned char>::type is a simple-type-specifier, and its type is simply the type of the template parameter.
Of course, you get a two-for-one with static_cast. This is the preferred casting method anyway.
The prefered method of casting in C++ is to use static_cast like so:
int a = static_cast<unsigned char>( '0' );
Try to add brackets int a = (unsigned char)('0');
or
typedef unsigned char uchar;
//inside main
int a = uchar('0');
No, it isn't - a function-style cast cannot have a space in its name.
A case for a C-style cast perhaps:
int main() {
unsigned char c = (unsigned char) '0' ;
}
I'm pretty sure it's a Microsoft extension.
No, it isn't. But why the cast in the first place? This is perfectly valid,
int a = '0';
Why are you even trying to cast from char to unsigned char and assigning that to an int? You're putting an unsigned value into a signed int (which is legal, but uncool).
Writing '0' gives you a char with value 48. You can try
int i = (int) '0';
That way, you take the char, cast it to an int, and use it. You could even say
int i = '0';
And that would do the same thing. What exactly are you trying to do?
Are you trying to get the integer 0 or the character '0' into it? The character '0' on most implementations namely is just the integer 48 but put into 8 bits.
The only difference between a char and an int is that char must be smaller or equal to short int. and int must be larger or equal than short int accordingly, this usually makes char 8 bits, short in 16, and in 32 nowadays.
Stuf like 'a'+2 to get 'c' works namely. If you have an array that is long enough, you can also index it like array[' '] to get index 32.
If you're trying to cast it to the integer value 0, that would require an actual function that determines that.