In addition to the great answer by @Stuart, you seem to be a little confused on how to handle sending values to your function to be changed, (here you are changing the vida member only). As noted in the other answer, on access, an array is converted to a pointer to its first element. C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3).
To make your function useful (as it is it hardcodes the entire operation), you should provide parameters for a pointer to dadospecas, the index to change and the new value to assign to the vida member. The caller is responsible for ensuring the index to change is within bounds (you can pass the number of elements as an additional index if desired)
If you put those pieces together and change the name of the function to reflect the fact you are only changing the vida member, you could do:
/* pass a pointer to the array as your parameter (inlcude index and value) */
void changeVida (dadospecas *a, int index, int newvida)
{
a[index].vida = newvida;
}
A short example showing the use, and fixing your indexing problem, could be written as:
#include <stdio.h>
#define NSTRUCT 2 /* if you need a constant, #define one (or more) */
typedef struct {
char nome;
int vida,
dano,
x,
y;
} dadospecas;
/* pass a pointer to the array as your parameter (inlcude index and value) */
void changeVida (dadospecas *a, int index, int newvida)
{
a[index].vida = newvida;
}
int main (void)
{
dadospecas stats[NSTRUCT] = {{'W', 3, 1, 4, 1}, {'F', 33, 11, 44, 14}};
for (int i = 0; i < NSTRUCT; i++) { /* loop over each struct */
changeVida (stats, i, stats[i].vida + 5); /* increment vida by 5 */
printf ("stats[%d].vida = %d\n", i, stats[i].vida); /* output new vida */
}
}
Example Use/Output
Where the example simply adds 5 to the existing value of the vida member:
$ ./bin/dadospecas
stats[0].vida = 8
stats[1].vida = 38
If You Pass The Address of stats
While there is no need to pass the address of stats, there is nothing to prevent you from doing it -- it is perfectly fine -- just unnecessary. For sake of argument, let's say you did. Continuing from my comment, in main stats is an array of type dadospecas [2], so when you take the address your type is pointer to array of dadospecas [2]. The formal type is dadospecas (*)[2]
So passing the pointer your function parameter would become: dadospecas (*a)[2].
Within your function to operate on your array, you would first need to dereference the parameter to allow you to operate on the elements of the array, e.g. (*a)[index] and finally to change the vida member you would have:
(*a)[index].vida = newvida;
The changes to the example above to pass the address of stats would be:
/* pass a pointer to array[NSTRUCT] as your parameter (inlcude index and value) */
void changeVida (dadospecas (*a)[NSTRUCT], int index, int newvida)
{
(*a)[index].vida = newvida;
}
int main (void)
{
dadospecas stats[NSTRUCT] = {{'W', 3, 1, 4, 1}, {'F', 33, 11, 44, 14}};
for (int i = 0; i < NSTRUCT; i++) { /* loop over each struct */
changeVida (&stats, i, stats[i].vida + 5); /* increment vida by 5 */
printf ("stats[%d].vida = %d\n", i, stats[i].vida); /* output new vida */
}
}
(same output)
It is simply a matter of keeping the levels of pointer indirection straight and observing C operator precedence.
Look things over and let me know if you have further questions.
void changeValues (dadospecas (*a)[2])statsis an array ofdadospecas[2]. When you take the address of the array, you have a pointer-to-arraydadospecas[2]dadospecas stats[2];the valid INDEXES are0, 1, NOT1, 2. (arrays are zero indexed in C) You invoke Undefined Behavior withstats[2].nome = 'F';...stats[2]...is beyond the end of your array.