0

I am a novice programmer trying to understand arrays in C. Specifically I want to take the numeric value of a variable and feed it into an array. I tried to assign the value to the array, but failed with error messages. Can someone explain, simplistically, how to push a value into an array and then be able to just access the last digit?

My last attempt:

#include <stdio.h>
unsigned int TMR0 = 158;


int main(void)
{
unsigned int V = TMR0; 
unsigned int Random[2] = {V};
printf("%d \n" , *(Random+2));
return 0;

Thanks.

chopnhack
  • 3
  • 4
  • 3
    When you say "access the last digit", are you saying you want "158", or do you mean you want "8"? I fear the latter is the case, in which case you need to rewind and learn about integers before you learn about arrays. – paddy Feb 10 '16 at 04:36
  • 2
    `*(Random+2)` is the same as `Random[2]` and that invokes UB as you access invalid memory locations beyond the array. – Spikatrix Feb 10 '16 at 04:39
  • You would benefit greatly from a good teaching resource. Buy a PDF or hard copy of C Primer Plus by Steven Prata. Read it cover-to-cover, and do all the examples and exercises at the end of each chapter. Most college students can do this over a long weekend. – Cloud Feb 10 '16 at 04:52
  • Could you make the question clearer ? It saves time for others. – Van Tr Feb 10 '16 at 04:54
  • 1
    @paddy - Yes, I am looking to access the last digit '8'. I am new to arrays with only very basic C understanding. Thanks – chopnhack Feb 10 '16 at 05:11
  • in C, an array offset starts at 0 and continues to (number of items in array -1). The `Random[2]` declares the array to contain 2 items. Those items are accessed as: Random[0] and Random[1]. The statement `unsigned int Random[2] = {V};` is trying to access `Random[2]`, which is beyond the upper bounds of the array, This results in undefined behaviour and can lead to a seg fault event. Note: the integer value 158 is NOT an array. The value fits into a single integer. to access the `8` use something like: ` unsigned int digit = V%10;` yielding the remainder of 158 divide by 10 – user3629249 Feb 10 '16 at 19:32

2 Answers2

2
unsigned int Random[2];

Array will be declared with two positions.

Random[0] Random[1] // two accessible positions in that array.

When you are assigning the value to the array,

unsigned int Random[2] = { V} ;

Value will be stored in the first position of array. Random[0].

*(Random+2) will access the position Random[2]. Which is not accessible position for this array. It will lead to undefined behaviour.

Another thing is if you need to assign the values to both the position you have to do like this.

unsigned int Random[2] = {V,V} ;

To access the last element in your array,

*(Random+1) or Random[1]

May this link will help.

Community
  • 1
  • 1
Karthikeyan.R.S
  • 3,991
  • 1
  • 19
  • 31
  • I see some of my error, the array needs to be declared as unsigned int Random [3] - to allow for three digits to be stored 1,5 and 8 from variable V. I am looking to access the last digit whose value is 8 (that would be Random[2] since the count begins at [0]. To be clear, V is a variable - can I simply put it in between {} and it will be read into the array? – chopnhack Feb 10 '16 at 05:20
  • @chopnhack When you use `unsigned int Random[3] = {V};`, `158` gets stored in `Random[0]`, not each digit in each array index. For that, you'll have to split the number into digits (using `% 10` or some other method) and assign each digit to each slot of the array. – Spikatrix Feb 10 '16 at 05:41
  • @Cool Guy - ouch, thanks! That was a big misunderstanding for me, I thought each cell in the array was to store only one number (0-9), like a bit! – chopnhack Feb 10 '16 at 05:44
  • @chopnhack, Strongly suggest have your instructor/TA explain how data is stored in memory (which should have been explained back in the class that discussed how computers work) also have them explain the hexadecimal number system and how to convert between different number bases, the concept of big and little Endian numeric representation, etc. Just to note: 158 will (with 4 byte/32 bit integers) look like: 0x0000009E or 0x9E000000 depending on the Endian-ness of the underlying hardware architecture. – user3629249 Feb 10 '16 at 19:44
  • @user3629249 - no instructor, hacking and self teaching along the way. Thanks! – chopnhack Feb 11 '16 at 03:02
1

You don't actually need an array to access digits of your number -- you just need math.

It's important to realise that "digit" implies a particular numeric base. In the computer, numbers are represented in binary. For convenience, they can be represented in our code using common bases: decimal, hexadecimal, and octal are the ones we generally use in languages like C.

So, to get the last digit in base 10, you would take the value modulo 10:

int val = 158;
int last_digit = val % 10;
printf( "%d\n", last_digit );

If you need to find digits other than the last, you can first perform integer division and then modulo:

int second_to_last_digit = (val / 10U) % 10;

Alternatively you can convert the number into a string, and then look at each character in that string. But I'm not going to go into that here, since it can be confusing to provide too much information to new programmers.

paddy
  • 60,864
  • 6
  • 61
  • 103
  • thanks Paddy! strcopy, etc. was what I thought I was ending up doing by creating the array, I kept messing with the type of data because of errors I received in compiler. I had avoided modulo and division because they call the math library - this is for a small pic mcu with limited word space memory. Can you elaborate on the conversion of the string? – chopnhack Feb 10 '16 at 05:41
  • Are you sure? Integer modulo and division shouldn't invoke math processor. Conversion to string will involve much more overhead. – paddy Feb 10 '16 at 05:59
  • I checked using modulo, it chews up about 63 word spaces, roughly a quarter of my total memory! I think you can see why I would prefer a less taxing approach :-) I have no clue yet how much the string operators will cost. – chopnhack Feb 10 '16 at 06:01
  • Do you need _all_ the digits, or just the last? – paddy Feb 10 '16 at 06:02
  • Hi paddy, yes I only need the last digit. – chopnhack Feb 11 '16 at 02:59
  • You can use `sprintf`, but internally it's going to be doing pretty much the same thing. I don't understand how this code is so much of a problem. More likely, the call to `printf` is chewing up all your space and the modulo is fine. Depending on the valid numeric range of your input, perhaps you could do some tricks with bit manipulation. Beyond this, you might need to post the question on a forum designed for embedded developers and ask why `val % 10` is so expensive for integers on your specific device. On this forum, we generally expect that to be an almost free operation. – paddy Feb 11 '16 at 03:33
  • no printf is being used at all as this is for a microcontroller. I am thinking along the lines of strcopy like you said: char RANDOM[1]; //create a dest. array for last digit from var. TMR0 strcpy(RANDOM, &TMR0[3]); //copy last digit into var. RANDOM – chopnhack Feb 11 '16 at 03:40
  • `strcpy` won't help you with this problem. Why don't you do a little experiment: `while( val > 9 ) val -= 10;` and see how many word spaces _that_ takes. – paddy Feb 11 '16 at 03:41
  • In response to your comment just a moment ago, you just aren't understanding the difference between a string and an integer. You simply can't do that. It is undefined behaviour and doesn't even come close to doing what you think it's doing. – paddy Feb 11 '16 at 03:43
  • No. This is starting to look like the classic [XY problem](http://xyproblem.info/). Why don't you just store your value internally as a string? I don't know. You have not said why it is an integer. What is your program for? You might need to post a new question. This one is answered, and it seems you now have a different problem. – paddy Feb 11 '16 at 03:46