How to reverse value store in memory block  - Page 1
Forum section: electronics / general

author: Dadu@
author_rank: Contributor
timestamp: February 20, 2022, 06:37:01 am
content: suppose the values are stored at the following memory location as follow0061FF18 = 'Y'0061FF19 = 'A'0061FF1A = 'J'0061FF1B = 'A'I want to write c program on PC that store values in reverse order without any other library function as follow0061FF18 = 'A'0061FF19 = 'J'0061FF1A = 'A'0061FF1B = 'Y'This is not homework assignment I am trying to solve example for practice. I am trying to understand how it can be solved before writing any code. My idea is something like this , I will have function in which i have to pass memory location, value and size I will need two loop inctrement and decrement. I can pass memory locations to function but I don't understand how to pass values

author: retiredfeline
author_rank: Frequent Contributor
timestamp: February 20, 2022, 07:15:49 am
content: Why do you need to pass the value?

author: Ian.M
author_rank: Super Contributor
timestamp: February 20, 2022, 07:22:54 am
content: Why would you need two loops if you already know the size?Algorithm to reverse an array in situ:Initialize two pointers to the start (low_ptr) and end (high_ptr) of the arrayDo{Swap the item at low_ptr with the one at high_ptrIncrement low_ptr pointer, decrement high_ptr}While high_ptr - low_ptr > 0I think you are badly confused by C functions. In C, you can *ONLY* pass parameters to (and return results from) a function by value. *EVERY* parameter is a value - you *cannot* pass a reference to a function. If you need to access something by reference inside a function, you have to pass the function the value of a pointer to it and dereference the resulting (new) pointer inside the function.

author: DavidAlfa
author_rank: Super Contributor
timestamp: February 20, 2022, 08:09:28 am
content: You need to store the whole array first, then copy in reverse order to the final destination.Code:char buffer, out;uint8_t count;// Store receiving datawhile (your condition){buffer[count++] = input_data;}// Reverse byte orderfor (uint8_t i=0; i<count; i++){out = buffer[(count-i)-1];}// Data ready on out buffer.

author: Siwastaja
author_rank: Super Contributor
timestamp: February 20, 2022, 08:43:29 am
content: Quote from: DavidAlfa on February 20, 2022, 08:09:28 amYou definitely don'tneedto do that. It's the most obvious algorithm, but also one that requires double the memory. The swapping algorithm shown by Ian.M does require only 1 element worth of extra memory (practically will be a CPU register) in addition to original buffer itself. The buffer is modified as a result.But sometimes you would take a copyanyway, in which case your copying solution is better.This simple example demonstrates how algorithm selection can't be done without knowing what the actual use case is. Depending on if you can accept modification of the original data, or if you want a copy of it, the optimal algorithm changes, too.Theinterfacewould be then something like:Code:void reverse_block(uint8_t * block, size_t len);for the non-copying version, andCode:void copy_reverse_block(uint8_t * restrict dst, uint8_t const * restrict src, size_t len); // dst and src are not allowed to overlapfor the copying version.In either case,block,dstandsrcare passed by value to the function, and can be modified freely without that modification affecting anything outside the function.But they are only pointers. When you dereference (i.e., access memory behind) these pointers, those changes will be visible to rest of the program.For example,src++;moves the pointer to the next element. Data itself does not change.But*src = 42;changes the data pointed to by src. This is by the way equivalent to writingsrc = 42;therestrictqualifier here just tells the compiler that we, the programmers, guarantee the areas won't overlap. You could also check that in the beginning of the function, in which case you could change the return type toint, so that you can return an error code (for example -1).

author: Dadu@
author_rank: Contributor
timestamp: February 20, 2022, 08:55:00 am
content: I have used two pointersCode:#include<stdio.h>int main (){char name = {'Y', 'A', 'J', 'A' };int i = 0;int j = 3;int n = 0 ;char *low_ptr = &name;char *high_ptr = &name ;for ( n= 0; n < 4; n++){low_ptr = high_ptr;printf("%c \n", *low_ptr);low_ptr++; high_ptr--;}return 0;}Program output when I complie codeAJAY

author: DavidAlfa
author_rank: Super Contributor
timestamp: February 20, 2022, 09:03:48 am
content: Since Dadu seems struggling a little I made a very simple example.For sure, can be done better:Code:void reverse_data (char * data, int size ){char *end = data+(size-1);char temp;for (int i=0; i<(size/2); i++){ // Reverse byte ordertemp = *data;*data++ = *end;*end-- = temp;}}int main (void) {char name[] = "654321 olleH";printf("%s", name); // "654321 olleHreverse_data(name, sizeof(name)-1); // Don't reverse last null char termination. Not needed for your example!printf("%s", name); // "Hello 123456"}

author: Dadu@
author_rank: Contributor
timestamp: February 20, 2022, 09:12:22 am
content: Quote from: DavidAlfa on February 20, 2022, 09:03:48 amI hope my previous program is working as i wanted ?After that i wanted to do the same thing with the functionCode:#include<stdio.h>void foo ( int i, int j, int size, char *low_ptr, char *high_ptr ){int n = 0 ;for ( n= 0; n < 4; n++){low_ptr = high_ptr;printf("%c \n", *low_ptr);low_ptr++; high_ptr--;}}int main (){int i = 0;int j = 3;int size = 4;char name = {'Y', 'A', 'J', 'A' };foo ( i, j, size, &name, &name );return 0;}as program give the output as it supposed to do .now in next step i would like to write code for unknow size of string I will try to implement it.

author: DavidAlfa
author_rank: Super Contributor
timestamp: February 20, 2022, 09:15:22 am
content: Quote from: Dadu@ on February 20, 2022, 08:55:00 amHmm you're only printing in reverse order, the buffer itself is untouched and still reversed.Was that your intention since the beginning?Checkout the result of my last code (I also made a HUGE mistake at first, sunday morning things):https://onlinegdb.com/qEDZsbSEk

author: Nominal Animal
author_rank: Super Contributor
timestamp: February 21, 2022, 01:56:35 am
content: Consider this example program:Code:#include <stdlib.h>#include <string.h>#include <stdio.h>char *reverse(char *buffer, size_t length){char *lo = buffer; /* Pointer to first character */char *hi = buffer + length - 1; /* Pointer to last character */char tmp;while (lo < hi) {tmp = *lo;*lo = *hi;*hi = cc;lo++;hi--;}return buffer;}int main(void){char text[] = "yajA";reverse(text, strlen(text));printf("%s\n", text);return EXIT_SUCCESS;}At the beginning of the first iteration of the loop in thereverse()function, we haveyajAlo^ ^hiAt the end of the first iteration, and at the beginning of the second iteration, we haveAajylo^^hiAt the end of the second iteration, we haveAjayhi^^loBecauselo < hiis not true anymore, there is no more iterations, and the function will return the pointer to the beginning of the buffer.If you continued the swaps as long aslo < length, i.e. swapped each character (twice), you'd end up withAajyhi^ ^loandyajAhi^ ^loand this is the reason you only do swaps as long as the positions to be swapped stay in the same order; so that you only swap each character once.The loop body can also be written more concisely asCode:while (lo < hi) {tmp = *lo;*(lo++) = *hi;*(hi--) = cc;}because post-increment (lo++) and post-decrement (hi--) occur after the expression has been evaluated; here,afterthe assignment. That is, the value will be assigned to where the pointer points to, and only then will the pointer be incremented or decremented.

author: SiliconWizard
author_rank: Super Contributor
timestamp: February 21, 2022, 02:44:41 am
content: Yeah, this is a very basic programming "exercise". Almost programming 101. Funnily enough, I remember this as an assignment I got in high school that I had to do in Pascal...All you have to do to reverse an array of any kind (including of course "strings") is to go through half the array and swap the "extreme" items in a "concentric" way. So let's assume A is the array and n is the number of items (and the indexing is zero-based). In pseudo-code:Code:for i = 0 to n/2-1swap A and A[n-1-i]That is reversing in place. But if you need to build the reverse in a separate array (say B), that's obviously just:Code:for i = 0 to n-1B = A[n-1-i]

author: brucehoult
author_rank: Super Contributor
timestamp: February 21, 2022, 06:34:53 am
content: Quote from: Dadu@ on February 20, 2022, 06:37:01 amI tend to think it's easier for beginners to understand (though a little more tedious) assembly language than C code. Here's some (64 bit) RISC-V in file reverse_chars.s:Code:.extern putchar.text.globl mainmain: # save return address on stackaddi sp,sp,-8sd ra,0(sp)la a0,myChrsli a1,4jal printCharsla a0,myChrsli a1,4jal reverseCharsla a0,myChrsli a1,4jal printChars# restore and returnld ra,0(sp)addi sp,sp,8retreverseChars:# not calling any other function -- nothing to saveadd a1,a1,a0 # make a1 point to last charaddi a1,a1,-1bge a0,a1,2f1: lb a2,0(a0)lb a3,0(a1)sb a2,0(a1)sb a3,0(a0)addi a0,a0,1addi a1,a1,-1blt a0,a1,1b2: retprintChars:# save return address and used s registers on stackaddi sp,sp,-24sd ra,0(sp)sd s0,8(sp)sd s1,16(sp)mv s0,a0mv s1,a11: lb a0,0(s0)jal putcharaddi s0,s0,1addi s1,s1,-1bnez s1,1b# add a newlineli a0,'\n'jal putcharld s1,16(sp)ld s0,8(sp)ld ra,0(sp)addi sp,sp,24ret.datamyChrs: .byte 'Y','A','J','A'And building and running it using Spike (qemu would do just as well):Code:$ riscv64-unknown-elf-gcc reverse_chars.s -o reverse_chars$ spike pk ./reverse_charsbbl loaderYAJAAJAYNote 1: The "bbl loader" is a slightly annoying message from "pk". QEMU doesn't do that.Note 2: to conform with the ABI I should have rounded up the stack frame sizes to the next multiple of 16. This won't matter on any current or near future machine.