Is it possible to use an array within a for loop? - c

This my code as it stands:
int sliderNum; // Variable Declaration //
// Loop Sequencer //
for (sliderNum = 41; sliderNum <= 48; sliderNum = sliderNum + 1)
However I need to change this so the loop no longer counts from 41-48 but instead counts e.g 73,71,34,46,52,4,17 etc. So a specific set of numbers one after another but not like counting normally.....hope that makes sense.
As you can probably tell, I'm pretty new to this programming stuff so any help would be greatly appreciated.
Cheers.

int a[] = {1,4,7,10};
for(int i=0; i<sizeof(a)/sizeof(a[0]); ++i)
{
....process a[i]
}
I recommend consulting a good book on c.
Regarding the code: This is basically looping over an array with iterations = size in bytes of the array / size in bytes of an element of array

You might even place the array literally within the for loop definion. This way, it somewhat resembles "with" statement, that is common in Python:
#define ARRAY_LEN(a) (sizeof(a)/sizeof(*a))
int main()
{
for (int a[] = {73, 71, 34, 46, 52, 4, 17}, i = 0; i < ARRAY_LEN(a); i++) {
// ...
}
}
Personally, I wouldn't write such code on production, as it may be questioned as "too clever", whereas putting the array at the top of loop seems to make it more readable.

Related

Is there a concise way (without loops) to create a linearly spaced array in C?

I'd like to create an array of numbers, 80 to 86, separated by increments of 0.5. I know I can create an array to represent this by writing
float Vector1[] = {80, 80.5, 81, 81.5, 82, 82.5, 83, 83.5, 84, 84.5, 85, 85.5, 86};
In Matlab, which is what I normally use, this is simply
Vector1 = 80:0.5:86;
In this particular case, it's not a big deal to write the array manually, but for a larger array it wouldn't be feasible to write out every entry. Is there similar functionality in C to create linearly spaced one-dimensional arrays of arbitrary bounds and step size? As stated in the title, I'd like to know if there's a solution that doesn't involve using a loop.
You could write a separate piece of code that generates the static declaration:
makevector.c:
#include <stdio.h>
int main()
{
float i;
int first = 1;
printf("float Vector1[] = { ");
for (i = 80; i <= 86; i += 0.5) {
if (first) {
first = 0;
} else {
printf(", ");
}
printf("%.1f", i);
}
printf(" };\n");
return 0;
}
Then run it:
gcc -o makevector makevector.c
./makevector > vector.c
While technically you still have a loop, it's done ahead of time to create code so that you don't need a loop in your real code.
No it is not possible without loops.All languages which offer functionality that you have asked uses a loop to achieve it.In C you just have to write your own.

C/CAPL defining one array from another

this is my first question here, please notice I'm very new to coding. Quick search doesn't helped me since I think the answer might be too simple.
Im writing some code in CAPL (a CANoe specific language based on C).
Lets have my scenario simplified: I have to read 10 values Input, but I'm just able to read one by a time (due to HW reasons).
My value is stored in a buffer (rsBuf), now I'm trying to define a help-array for everytime I read the value (rsBuf1 ... 10).
At the end I will create another array with added values of rsBuf1 ... rsBuf10.
for every "read-action", I want to define
rsBuf1 = rsBuf;
rsBuf2 = rsBuf; and so on...
error: for "rsBuf1 = rsBuf;" Error 1112 at (732,16): operand types are incompatible.
Compilation failed -- 1 errors, 0 warnings
my "real" values:
variables
{
byte rsBuf[1024];
byte rsBuf1[1024];
}
is there an easy way to do this one-array-from-another?
I also tried some other notations I found, like rsBuf1 = {rsBuf}, but wasn't helping. Of course I could define
rsBuf1[1]=rsBuf[1];
...
rsBuf1[1024]=rsBuf[1024];
but that would be a waste of time I guess.
Thanks in advance, cheers Robert
You can't copy arrays through assignment in C, because the syntax does not allow it. The best solution is to use the memcpy function.
Alternatively, if it makes sense for the program design, you could put the arrays inside a wrapper struct:
typedef struct
{
int array [5];
} array_wrapper_t;
array_wrapper_t this = {1,2,3,4,5};
array_wrapper_t that;
that = this;
This should yield identical machine code as a call to memcpy.
Option 1
You can use memcpy as follows to copy the entire array:
memcpy(rsBuf1, rsBuf, elcount(rsBuf));
The following would copy the first four bytes:
memcpy(rsBuf1, rsBuf, 4);
Option 2
Optionally you could define your copy-function, see the copy_buffer() implementation:
variables
{
byte rsBuf[1024] = {1, 2, 3, 4, 5, 6, 7, 8};
byte rsBuf1[1024];
}
on start
{
print_buffer(rsBuf, 8);
print_buffer(rsBuf1, 8);
copy_buffer(rsBuf1, rsBuf, elcount(rsBuf));
print_buffer(rsBuf1, 8);
}
void copy_buffer(byte dest[], byte src[], long len)
{
int i;
for (i = 0; i < len; i++)
dest[i] = src[i];
}
void print_buffer(byte buf[], byte len)
{
int i;
writeLineEx(0, 0, ">");
for (i = 0; i < len; i++)
writeEx(0, 0, " 0x%02x", buf[i]);
}

Can I use labels as index in C global data table?

I have a large global array in which I keep changing some of the values which when compiled for different purposes requires the table to be altered. Basically the table as a core structure and based on different purposes additional values may get added/removed from it.
The values are somewhat like:
int global_array[] =
{
...
6, 6, 78, 9,
12,
13,5
19,
47, 768, 98, 89
...
};
I need to access some of core structure values (lets say "12" here) inside these table. So while compiling for different purposes, index of concerned value ("12") changes. For same reason I cannot keep this table as structure. Keep in mind this is a huge table and for some reason we don't write values in uniform fashion (read linear).
So for every new purpose I have to manually count index of value "12" which is tedious. I want a future proof process.
I was wondering if I could use something like:
int global_array[] =
{
...
6, 6, 78, 9,
INDEX: 12,
13,5
19,
47, 768, 98, 89
...
};
And access/modify values at run-time as below:
*(uint8 *)INDEX = 20;
You can keep additional pointer variables around that point to specific entries. Whenever needed, you can adjust the array entry the pointer points to.
Example:
#include <stdio.h>
int global[] = {1,2,3,4,5,6,7};
int *idx = &global[0];
int main() {
*idx = 20;
printf("%d\n", *idx);
return 0;
}
Alternatively, you could use a preprocessor macro (if the location that is referred to is known at compile time and will not change):
#include <stdio.h>
int global[] = {1,2,3,4,5,6,7};
#define INDEX (global[0])
int main() {
INDEX = 20;
printf("%d\n", INDEX);
return 0;
}
Given you only need to do this once at program start, maybe you just need a function that does the counting for you.
Example:
#include <stdio.h>
int global[] = {1,2,3,4,5,6,7};
int find_index(int value, int *array, size_t size) {
for (int i = 0; i < size; i++)
if (array[i] == value)
return i;
return -1;
}
int main() {
int value = 4;
int index = find_index(value, global, sizeof(global)/sizeof(*global));
printf("index of %d: %d\n", value, index);
return 0;
}
Here's the output:
$ gcc tt.c -std=c99 && ./a.out
index of 4: 3
If the positions of lots of entries needs to be tracked throughout the entire runtime of the application you should consider using a key-value storage (e.g., a binary search tree) to keep track of the values' indices. You should then use special methods that encapsulate the update and retrieval operations that will also adjust the indices stored in that "index" data structure.
From ISO/IEC9899:
6.8.6.1 The goto statement
Constraints
1 The identifier in a goto statement shall name a label located somewhere in the enclosing function.
A goto statement shall not jump from outside the scope of an identifier having
a variably modified type to inside the scope of that identifier.
As a global aray is not located in an enclosed function, this is not allowed!
C does not provide any syntax to do what you want.
One way to solve this so you don't have to count something with each change, is to have a tool of yours do the counting. After all, machines are good at counting things. For example, you could mark the interesting postitions in the initializer with a special comment, i.e.
int global_array[] =
{
6, 6, 78, 9,
12, /* INDEX12 */
13,5,
19,
47, 768, 98, 89
...
};
The index for the array element is then found by counting the commas from the start of the declaration, minus one. Turn the result into a compile-time macro with -DINDEX12=42, et voilĂ ! All you need is an idea of where the declaration starts (putting it in a separate header file is the easy route), and run for example
$ awk '/global_array/,/INDEX12/ { commas += gsub(/,/, ",") }
END {print "-DINDEX12=" commas - 1}' file.h
-DINDEX12=4
This is easily extended to deal with any number of INDEXNNN macros. Beware of the potential off-by-one for the last array initializer (which doesn't have a comma in your snippet, but C does allow it...)
Placing this preprocessing in a snugly Makefile left as an exercise.

For loop with specific function

I have a small problem with a program I am working on.
My program executes a function on an array. The function only can execute the commands on the first 16 elements of the array.
I now want to make a loop so that the function can work on more than 16 elements of the array. Here's my thought, but it ended up in an infinite loop:
int l = 0;
for (int i=0; i<=size; i+16)
{
for (int j=0; j<=16;j++)
{
FUNCTION(INARRAY; OUTARRAY);
}
}
Next problem is that the function will only walk through 16 Elements of the array and ignore the rest.
What is the best way to make it walk through the next 16 elements and save it in the outbuffer as the following elements?
As I adapt the solution it still does only process through the first 16 elements and then doesn't continue with the next 16.
This:
i + 16
does nothing to change the value of i, so that loop never terminates. That expression just computes the value of i + 16, but the result is thrown away.
To change the value of a variable, use assignment (=) operator, like i = i + 16 or i += 16.
I think I have what you are looking for. You would have to implent it and check it out. Be warned though that this worked if your arrays size is a multiple of 16, otherwise there will be remaining elements paired with already processed elements.
int count16 = 0;
var tempAr[16];
for (int i=0; i<numOfArraysToGoThrough; i++)
{
tempAr[count16]=numOfArrayToGoThrough[i];
if ( count16 == 15)
{
FUNCTION (tempAr, OUTARRAY);
count16=0;
}
else
count16+=1;
}
figured this one out some time ago
here's how it worked for me
for (uint64_t i=0; i<size; i+=16)
{aes_encrypt(tfm, &tempbuffer[i], &inbuffer[i]);}
this does the following
calling aes_encrypt will encrypt the first 16 bytes of data in the array,
the for loop then jumps to the 16th entry and performs the encryption again

Heap sort "visual" tree prints extra zeros

I've learned Heap Sort with a visual representation of it with the infamous tree diagram (here), so I set out to find a way to print one out and I've progressed very well so far. My only problem seems to be that if, there aren't any more values to fill up on the line, my program seems to print zeros for some reason.
I'm certain it's probably an error in my code, or an extra line that needs to be added but I'm also looking for advice if this was the best approach. Code below.
#include <stdio.h>
int HeapArray[] = {165, 245, 398, 426, 575, 661, 775, 895, 901, 1028, 1184, 1283, 1350,1427, 1598, 1698};
int main()
{
int i = 0, numL = 1;
int j, k;
for(k = 0; k < 6; k++)
{
if(HeapArray[i] == 0)
break;
for(j = 0; j < numL;j++)
{
printf("%d ", HeapArray[i]);
i++;
}
printf("\n");
numL *= 2;
}
return 0;
}
Things to mention:
In the other most for-loop, I've using the value 6 as the maximum lines to print, however the program stops printing on the line with the last array values in it.
I haven't implemented any alignment to make the diagram 100% accurate since it seemed easy enough to leave for last (i.e. no extra code to confuse me).
Your index i is probably going past the bound of the array
You have 16 elements, so the first time you print 1, then you print 2, then 3, etc
In total you would print 1 + 2 + 4 + 8 = 15 on the fourth line.
When you get to the last line (fifth line), you only have one element to print. However, your inner loop goes from 0 to 16, going past the bounds of the array (and so it prints 0s)
You should add a check in the inner loop to make sure you still have enough elements.
Note that I also highly recommend you actually add a 0 element to the end of the array, so you are not relying on memory outside of its bounds

Resources