How to pre-define an array in c? - c

#include <stdio.h>
#include <math.h>
#define Hey {0.9501, 0.2311, 0.6068, 0.4860, 0.8913, 0.7621, 0.4565, 0.0185, 0.8214, 0.4447, 0.6154, 0.7919, 0.9218, 0.7382, 0.1763, 0.4057, 0.9355, 0.9169, 0.4103, 0.8936, 0.0579, 0.3529, 0.8132, 0.0099, 0.1389, 0.2028, 0.1987, 0.6038, 0.2722, 0.1988, 0.0153, 0.7468, 0.4451, 0.9318, 0.4660, 0.4186, 0.8462, 0.5252, 0.2026, 0.6721, 0.8381, 0.0196, 0.6813, 0.3795, 0.8318, 0.5028, 0.7095, 0.4289, 0.3046, 0.1897, 0.1934, 0.6822, 0.3028, 0.5417, 0.1509, 0.6979, 0.3784, 0.8600, 0.8537, 0.5936, 0.4966, 0.8998, 0.8216, 0.6449, 0.8180, 0.6602, 0.3420, 0.2897, 0.3412, 0.5341, 0.7271, 0.3093, 0.8385, 0.5681, 0.3704, 0.7027, 0.5466, 0.4449, 0.6946, 0.6213, 0.7948, 0.9568, 0.5226, 0.8801, 0.1730, 0.9797, 0.2714, 0.2523, 0.8757, 0.7373, 0.1365, 0.0118, 0.8939, 0.1991, 0.2987, 0.6614, 0.2844, 0.4692, 0.0648,0.9883}
float average(float Hello[]){
int i;
float sum;
for (i=0; i<100;i++) {
sum+= Hello[i];
}
return sum/100;
}
int main(){
printf("%f\n",average(Hey));
//so here the compiler says that expected error without giving me what the error actually is. and i suspect because of the bad definition of the vector that i have at the very beginning of my code.
}
Yeah, so as i stated in my comment the problem is with the c preprocesses as its referred to here in stack overflow. is my predefinition for the array Hey wrong? and why?

Usually this is how to predefine an array in C, omit the size and provide the values in brackets. Eg,
const float Hey[] = {0.9501, 0.2311, 0.6068 };

If you really want to, you can do something like this.
#include <stdio.h>
#include <math.h>
#define HEY_INIT { 0.9501, 0.2311, 0.6068, 0.4860, 0.8913, 0.7621, 0.4565, 0.0185, 0.8214, 0.4447, 0.6154, 0.7919, 0.9218, 0.7382, 0.1763, 0.4057, 0.9355, 0.9169, 0.4103, 0.8936, 0.0579, 0.3529, 0.8132, 0.0099, 0.1389, 0.2028, 0.1987, 0.6038, 0.2722, 0.1988, 0.0153, 0.7468, 0.4451, 0.9318, 0.4660, 0.4186, 0.8462, 0.5252, 0.2026, 0.6721, 0.8381, 0.0196, 0.6813, 0.3795, 0.8318, 0.5028, 0.7095, 0.4289, 0.3046, 0.1897, 0.1934, 0.6822, 0.3028, 0.5417, 0.1509, 0.6979, 0.3784, 0.8600, 0.8537, 0.5936, 0.4966, 0.8998, 0.8216, 0.6449, 0.8180, 0.6602, 0.3420, 0.2897, 0.3412, 0.5341, 0.7271, 0.3093, 0.8385, 0.5681, 0.3704, 0.7027, 0.5466, 0.4449, 0.6946, 0.6213, 0.7948, 0.9568, 0.5226, 0.8801, 0.1730, 0.9797, 0.2714, 0.2523, 0.8757, 0.7373, 0.1365, 0.0118, 0.8939, 0.1991, 0.2987, 0.6614, 0.2844, 0.4692, 0.0648, 0.9883 }
static const float Hey[] = HEY_INIT; // global array
float average(float Hello[]) {
int i;
float sum;
for (i = 0; i < 100; i++) {
sum += Hello[i];
}
return sum / 100;
}
int main(void) {
printf("%f\n", average(Hey));
return 0;
}

example: an array containing 4 integer values of type int called abc could be represented as: int abc [4];
by default, regular arrays of local scope (in this example, those declared inside the function) are ignored.
But the elements in an array can be explicitly initialized to specific values when it is declared, by enclosing those initial values in braces {}. For example:
int abc [4] = { 1, 2, 47, 50, -371 };
in other case you can let empty the brackets so you can initialize them when the program is running e.g. int abc [] ; or you can use a matrix like :int abc [] []; with X lines & Y columns.

Related

memory access error when sorting struct field

i have some problems sorting a struct field and cannot find the answer why this is happening...
The Error message when i run the program says "Memory access error (German: Speicherzugriffsfehler (Speicherabzug geschrieben)). The error only comes whenever i try the proceed one of the following lines in the bubblesort:
x= *mannschaften[i];
*mannschaften[i]=*mannschaften[i+1];
*mannschaften[i+1]=x;
vertauscht=1;
I have the feeling that i might have to save memory with malloc() or calloc() at some point, but i don't know how to use this,yet...
Thank you for your help!
Best regards
kazimir
You can see the the entire code below:
#include <stdio.h>
#include <string.h>
typedef struct
{
char* nation;
int goals_scored;
int goals_conceded;
} Team;
typedef struct
{
Team* t1;
Team* t2;
int goals_t1;
int goals_t2;
}Spiel;
void ergebnis_eintragen(Spiel s)
{
s.t1->goals_scored = s.goals_t1;
s.t2->goals_scored = s.goals_t2;
s.t1->goals_conceded = s.goals_t2;
s.t2->goals_conceded = s.goals_t1;
}
void ausgabe (Team* mannschaften[8])
{
Team x;
int m=8;
int vertauscht;
do
{
vertauscht=0;
for (int i=0;i<8;i++)
{
if (mannschaften[i]->goals_scored<mannschaften[i+1]->goals_scored)
{
x= *mannschaften[i];
*mannschaften[i]=*mannschaften[i+1];
*mannschaften[i+1]=x;
vertauscht=1;
}
else if (mannschaften[i]->goals_scored==mannschaften[i+1]->goals_scored||mannschaften[i]->goals_conceded>mannschaften[i+1]->goals_conceded)
{
x = *mannschaften[i];
*mannschaften[i]=*mannschaften[i+1];
*mannschaften[i+1]=x;
vertauscht=1;
}
}
m-=1;
}
while (m>1 && vertauscht);
for (int i=0;i<8;i++)
printf("\nNation: %s\nTore: %d\nGegentore: %d\n",mannschaften[i]->nation,mannschaften[i]->goals_scored,mannschaften[i]->goals_conceded);
}
int main (void)
{
Team t1={"Kroatien",0,0};
Team t2={"Brasilien",0,0};
Team t3={"Niederlande",0,0};
Team t4={"Argentinien",0,0};
Team t5={"Marokko",0,0};
Team t6={"Portugal",0,0};
Team t7={"England",0,0};
Team t8={"Frankreich",0,0};
Spiel s1={&t1,&t2,5,3};
Spiel s2={&t3,&t4,5,6};
Spiel s3={&t5,&t6,1,0};
Spiel s4={&t7,&t8,1,2};
Spiel s5={&t4,&t1,3,0};
Spiel s6={&t8,&t5,2,0};
Spiel s7={&t1,&t5,2,1};
Spiel s8={&t4,&t8,7,5};
Team* ptr_team[8];
ptr_team[0] = &t1;
ptr_team[1] = &t2;
ptr_team[2] = &t3;
ptr_team[3] = &t4;
ptr_team[4] = &t5;
ptr_team[5] = &t6;
ptr_team[6] = &t7;
ptr_team[7] = &t8;
ergebnis_eintragen(s1);
ergebnis_eintragen(s2);
ergebnis_eintragen(s3);
ergebnis_eintragen(s4);
ergebnis_eintragen(s5);
ergebnis_eintragen(s6);
ergebnis_eintragen(s7);
ergebnis_eintragen(s8);
ausgabe(&ptr_team[0]);
}
I already tried looking for a simular question, but couldn't find anything...
In the for loop
for (int i=0;i<8;i++)
{
if (mannschaften[i]->goals_scored<mannschaften[i+1]->goals_scored)
when i is equal to 7 then expressions like this
mannschaften[i+1]->goals_scored)
access memory outside the array ptr_team defined in main.
You could write your loop like for example
for (int i=1;i<8;i++)
{
if (mannschaften[i-1]->goals_scored<mannschaften[i]->goals_scored)
//...
Also it seems in this if statement
else if (mannschaften[i]->goals_scored==mannschaften[i+1]->goals_scored||mannschaften[i]->goals_conceded>mannschaften[i+1]->goals_conceded)
you mean the logical operator && instead of the logical operator ||
else if (mannschaften[i]->goals_scored==mannschaften[i+1]->goals_scored && mannschaften[i]->goals_conceded>mannschaften[i+1]->goals_conceded)
Using the variable m as is in the do-while loop does not make a great sense. It is enough to use the variable vertauscht
do
{
//...
} while ( vertauscht);
And it is a bad idea to use magic numbers like 8.
You could declare your function like
void ausgabe (Team* mannschaften[], size_t n );
and call it at least like
ausgabe( ptr_team, 8 );
Then within the function you should use the variable n instead of the magic number 8 as for example
for ( size_t i = 1;i < n;i++ )
Otherwise you will need to change your function each time when the size of the passed array will be changed.
You should always write a more general function.
Pay attention to that your program will look much better and will be more readable if you will use English words for identifiers.

values are returned but not seeing outputs

I'm new to programming and trying to learn C here. Below is my toy program.
#include <stdlib.h>
#include <stdio.h>
int cmp(int a, int b)
{
if (a > b)
{
return a;
}
else
{
return b;
}
}
int main()
{
cmp(10, 20);
printf("testing...");
return 0;
}
My question is, in the main function, cmp() function is called, and the value 10 and 20 is passed into cmp() function.
In this case, b is larger than a, so it goes to the else branch. b should be returned, which is 20 in this case. Why am I not seeing any outputs on the terminal?
Your function will return an integer value; however, in your "main" function you call your "cmp" function but don't do anything with it. The "printf" function is only instructed to print out "testing..." currently. Here is one possible suggestion for checking the output of your function in the "main" function.
int main()
{
printf("Testing the value of cmp(10, 10) is %d\n", cmp(10, 20));
return 0;
}
Hope that helps.
Regards.

Static array initialization in C

Consider the following statements
typedef struct {
int member1;
int member2;
}Custom_t;
void ISR(void)
{
static Custom_t struct1[SOME_CONSTANT];
......
......
}
How can I initialize all member2 variable to a single value in C programming?
If I iniatilize the structure like the one shown below, then there is chance of somebody changing the "SOME_CONSTANT" in a header file and forgetting to update the list.
Another solution would be to give the structure a global scope for the current file. But the only function which uses the structure is the ISR().
void ISR(void)
{
static Custom_t struct1[SOME_CONSTANT] = {
{0, 3},
{0, 3},
......
......
};
......
......
}
Is there any method to solve this problem in C?
You can use Designated Initializers and do it in this way:
#include <stdio.h>
#define SOME_CONSTANT 30
typedef struct {
int member1;
int member2;
} Custom_t;
int main(void)
{
static Custom_t struct1[SOME_CONSTANT] =
{
[0 ... SOME_CONSTANT - 1].member2 = 30
};
printf("%d\n", struct1[25].member2);
printf("%d\n", struct1[19].member2);
printf("%d\n", struct1[0].member2);
return 0;
}
How about to add hard-coded compiling time checking against SOME_CONSTANT in the .c file (e.g. right before the initializer)?
#if SOME_CONSTANT != <some_hard_code_value>
#error "SOME_CONSTANT is not equal to <some_hard_code_value>"
#endif
The rational of this "hard-code" is whenever the SOME_CONSTANT is changed, the initializer need be updated, as well as the compiling time checking.
You don't need to specify the array size in advance, you can compute it later:
static Custom_t struct1[] = {
{0, 3},
{0, 3},
{13,3},
};
#define SOME_CONSTANT (sizeof struct1 /sizeof struct1[0])
or: use __LINE__ to compute the number of elements.
I've had to do something like this with projects with a configurable number of sensors :
[custom_t.h]
typedef struct {
int member1;
int member2;
}Custom_t;
#define MAX_CUSTOM_T 4
Custom_t *new_Custom_t (int member1, int member2);
[custom_t.c]
#include "custom_t.h"
static Custom_t g_Customt[MAX_CUSTOM_T];
static uint8 g_numCustom_t = 0;
Custom_t *new_Custom_t (int member1, int member2)
{
if ( g_numCustom_t < MAX_CUSTOM_T )
{
Custom_t *new_obj = &g_Customt[g_numCustom_t++];
new_obj->member1 = member1;
new_obj->member1 = member2;
return new_obj;
}
else
{
// throw exception?
// or go into while(1)?
// or software breakpoint if debug?
// or just...
return NULL;
}
}
[main.c]
#include "custom_t.h"
Custom_t *myCustom1;
Custom_t *myCustom2;
Custom_t *myCustom3;
somefunc()
{
myCustom1 = new_Custom_t (0,3);
myCustom2 = new_Custom_t (1,3);
myCustom3 = new_Custom_t (2,3);
// do stuff
}
It means if you want to create a new one, you may or may not need to update MAX_CUSTOM_T depending on its size already, but will just have to add a new line call to new_Custom_t(int,int). A Disadvantage though is it is slightly complex for what you might need, and if you ever want to add more members to initialize, you'll need to update the parameters passed into the new_ function to suit. This can be done instead with a sending a single separate structure for parameters rather than multiple parameters (a bit like MPLAB harmony).

Segmentation fault happened while calling a correct function

I am solving a 0-1knapsack problem.
I solved the problem by brute force algorithm.
In main.cpp
int main(int argc, char *argv[])
{
......
int solution;
solution = bruteForce();
......
}
The strange thing is, when I implement the bruteForce() in main.cpp, my program works correctly, however, after I move the bruteForce() to bruteForce.cpp and included it in main.cpp, the program will produce segmentation fault when calling the bruteForce().
Here's how I move bruteForce() to bruteForce.cpp.
First I created a header functions.h(because I want to solve the problem by other method after implement brute force successfully)
functions.h:
#include "global.h"
int bruteForce();
int multiplication( int );
And then I move bruteForce() to bruteForce.cpp
#include <iostream>
#include <stdlib.h>
#include <vector>
#include "global.h"
#include "functions.h"
using namespace std;
int bruteForce()
{
int bestValue = 0;
int j, tempSize, tempValue;
int bestChoice[n+1];
for(int i=0; i<multiplication(n); i++)
{
tempSize = 0;
tempValue =0;
j = n;
while(x[j]!=0 && j>0)
{
x[j] = 0;
j--;
}
x[j] = 1;
for(int k=1; k<=n; k++)
{
if(x[k] == 1)
{
tempSize += size[k];
tempValue += value[k];
}
}
if((tempValue > bestValue) && (tempSize <= S))
{
bestValue = tempValue;
for(int p=1; p<=n; p++)
bestChoice[p] = x[p];
}
}
for(int p=1; p<=n; p++)
x[p] = bestChoice[p];
return bestValue;
}
In global.h, I declared some glabal variables:
#include <vector>
using std::vector;
static int n, S;
static vector<int> value, size, x;
The gdb debugger shows
Program received signal SIGSEGV, Segmentation fault.
0x08049308 in main()
Any idea about why this happens?
Thanks in advance.
Oh BTW, if you need more info, here's the package.
You can first type make in the root of this package. Then type this to execute.
./bin/01knapsack -BF inputs/n5S11.in n5s11.out
You shouldn't put your variables in a header file. When you include that from both your source files, both will get their own individual copy of that variable - and thus you wont be able to transfer data between your functions in the way you think (or at least, that's my understanding of how it should work - I'll admit that I'm not 100% sure what actually happens).
The best way to transfer data to a function is to use parameters though. Call the function with whatever it needs, and return data either through the function return value, or through a pointer or reference parameter. Using global variables for stuff like this is error prone (as you have seen), and it's much less clear for others looking at your code.
If you absolutely want to use global variables, declare them in one of your source files, and put them in your global header file with an extern statement in front of it. When you then include the header from another file, extern tells the compiler that it shouldn't actually create the variable itself, but rather that it is provided by another object file.
So, in main.cpp:
int n, S;
vector<int> value, size, x;
And in global.h:
extern int n, S;
extern vector<int> value, size, x;

Can't understand this conversion from C to Assembly

I'd like to know if someone can explain me the solution to this problem:
the code is:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int c[20];
int n;
} t_coda;
t_coda coda;
void init(t_coda *coda) {
coda->n = 0;
}
void add(t_coda *coda, int x) {
if (coda->n < 20)
coda->c[(coda->n)++] = x;
}
main() {
init(&coda);
coda->n=1;
coda->c[0]=2;
add(&coda,3);
add(&coda,4);
}
And I need to know the corresponding instruction of: coda->n = 0; and coda->c[(coda->n)++] = x; in simplesem (an assembly-like semantic);
The solution is:
set D[D[0]+3]+20, 0
for the first question
and:
set D[D[0]+3]+D[D[D[0]+3]+20], D[D[0]+4]
set D[D[0]+3]+20, D[D[D[0]+3]+20] + 1
for the second one;
D is the Data stack, and D[0] return the value contained in the 0-cell of the data
Thank you
I would guess that...
D[0]+3 is a reference to the address of coda (the *coda in the function call)
D[D[0]+3] is a lookup of the data at the address where coda is stored
D[D[0]+3]+20 is an offset of 20 from where coda begins, thus moving past coda->c (which is 20 items) to get to coda->n.
That should help you to understand the first one; the same ideas can be extended to the second.

Resources