These are two functions I used for swapping variables using pointers while performing selection sort using the function selectionSort(int *,int). But after sorting, some elements of the array become zero.
void selectionSort(int *x,int len){
int i,j,max;
for(i=len-1;i>=0;i--){
max = 0;
for(j=1;j<=i;j++){
if(x[j]>x[max]){
max = j;
}
}
swap(x+max,x+i);
}
}
void swap(int *a,int *b){
//This one works perfectly
int temp;
temp=*b;
*b=*a;
*a=temp;
}
void swap(int *a,int *b){
//This one gives unexpected results
*a=*a+*b;
*b=*a-*b;
*a=*a-*b;
}
Swapping two integers using arithmetic operators can result in integer overflow. Better to stick with the traditional approach.
BTW, you can use old school bitwise XOR operator for swapping (used to swap values in registers) but it would not give you any benefit over the method that uses a temporary variable. These days compiler are smart enough to optimize the code.
if (*a == *b) // If both integers are same then do not perform swap operation
return;
*a ^= *b;
*b ^= *a;
*a ^= *b;
The second swap algorithm does not work if both pointers point to the same variable which happens here if max == i:
swap(x+max,x+i);
Demonstration:
#include <stdio.h>
#include <string.h>
#include <assert.h>
void swap(int *a, int *b) {
//This one works perfectly
int temp;
temp = *b;
*b = *a;
*a = temp;
}
void swap_KO(int *a, int *b) {
//This one gives unexpected results
*a = *a + *b;
*b = *a - *b;
*a = *a - *b;
}
int main()
{
int a = 22, b = 33;
swap(&a, &b);
assert(a == 33 && b == 22); // OK
swap_KO(&a, &b);
assert(a == 22 && b == 33); // OK
swap(&a, &a); // OK
assert(a == 22);
swap_KO(&a, &a); // won't work
assert(a == 22);
}
Related
A function receives two integer pointers, int* a and int* b. Set the value of *a to their sum, and *b to their absolute difference.
There is no return value, and no return statement is needed.
I got the values for *a but I'm unable to get the code for *b.
#include <stdio.h>
void update(int *a,int *b);
int main() {
int a, b;
int *pa = &a, *pb = &b;
scanf("%d %d", &a, &b);
update(pa, pb);
printf("%d\n%d", a, b);
return 0;
}
void update(int *a,int *b)
{
*a+=*b;
*b=*a-*b;
}
You may use a temporally variable to store value of *a and then use it:
int tmp = *a;
*a += *b;
*b = abs(tmp - *b);
A little cleanup. Only the function needs pointers. Your main does not.
#include <stdio.h>
#include <stdlib.h> // abs()
void sum_and_diff( int * a, int * b )
{
int sum = *a + *b;
int diff = abs( *a - *b );
*a = sum;
*b = diff;
}
int main(void)
{
int a, b;
printf( "a? " ); scanf( "%d", &a );
printf( "b? " ); scanf( "%d", &b );
sum_and_diff( &a, &b );
printf( "sum = %d\n", a );
printf( "absolute difference = %d\n", b );
return 0;
}
A simple answer (the simplest?), that doesn't require temporary variables or external functions like abs(), is:
void update(int *a, int *b)
{
*a += *b;
*b = *a-*b-*b;
}
It fixes your code by also subtracting the "extra" *b you just added to *a
So I was practicing some coding about how functions work and I ran into a problem:
The code is meant to reverse a number. The algorithm works perfectly well so I don't have any problem with that. But I want to use functions in my code so I edited it like below and somehow it doesn't work anymore(there was no error, but when I run the code, after I entered in the first scanf, the code stopped and stays like that, no response). Can someone help me with this pls (This question may sound a little stupid but I'm just trying to be better at it :v)
Code:
#include <stdio.h>
#include <string.h>
int input(int *a) {
scanf("%d", &*a);
}
int revint(int *a, int *b){
int c;
while(a != 0)
{
c = *a % 10;
*b *= 10;
b += c;
*a /= 10;
}
return *b;
}
int output(int b) {
printf("%d", b);
}
int main(){
int a;
int b = 0;
input(&a);
revint(&a, &b);
output(b);
return 0;
}
There are several issues in your code:
input() and output() do not have a return statement and should be declared to return void in your code.
It makes more sense for input() to return the value rather then fill a pointer parameter. Therefore in my version input() does return a proper int value.
Several occurrences of a, b in revint() should be *a,*b (since a and b are pointers and we need to de-reference it first).
See the code below:
int input(void) {
int a;
scanf("%d", &a);
return a;
}
int revint(int *a, int *b)
{
int c;
*b = 0;
while (*a != 0)
{
c = *a % 10;
*b = *b * 10 + c;
*a /= 10;
}
return *b;
}
void output(int b) {
printf("%d", b);
}
int main(void)
{
int a;
int b = 0;
a = input();
revint(&a, &b); // passing the addresses
output(b);
return 0;
}
NOTE: For simplicity the input() function doesn't validate that scanf() actually succeeded. In should better be done in the real code in which the user is handling.
Better scanf():
if (scanf("%d", &a) != 1)
{
fprintf(stderr, "bad input\n");
exit(1);
}
In the real code the user can consider retrying getting the input as long as it is invalid.
Update:
As you can see in #Gerhard's answer, revint could be re-written to avoid the pointer semantics altogether. It will indeed make the code simpler and for this particular use case I actually think it is better.
My answer was written trying to maintain as much as possible the semantics that the user introduced in his question code. So I suggest you apply my solution only if it really makes sense for you to pass pointers.
input changed to use the pointer correctly (&*a).
Removed the pointers to revint as it is not helping and your code had an point error there (b += c; modifies pointer not value).
#include <stdio.h>
#include <string.h>
void input(int *a) {
scanf("%d", a);
}
int revint(int a){
int b = 0;
int c;
while(a != 0)
{
c = a % 10;
b *= 10;
b += c;
a /= 10;
}
return b;
}
int output(int b) {
printf("%d", b);
}
int main(){
int a;
int b = 0;
input(&a);
b = revint(a);
output(b);
return 0;
}
I m learning c (programming in ANSI c -> fifth edition) and facing the below issue:
I'm implementing one program with pointers to functions
#include<stdio.h>
//void swap (int *a, int *b); //function declaration
int main()
{
int m = 25;
int n = 100;
printf("m is %d, n is %d\n", m, n);
swap(&m, &n); //calling a function
printf("m is %d, n is %d\n", m, n);
return 0;
}
void swap (int *a, int *b) //function implementation
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
in the above program comment the line void swap (int *a, int *b); then program run file but give one suggestion here facing the issue why here give the suggestion
main.c:10:3: warning: implicit declaration of function ‘swap’ [-Wimplicit-function-declaration]
main.c:16:6: warning: conflicting types for ‘swap’
main.c:10:3: note: previous implicit declaration of ‘swap’ was here
m is 25, n is 100
m is 100, n is 25
when I m uncomment this line void swap (int *a, int *b); then program run fine
#include<stdio.h>
void swap (int *a, int *b); //function declaration
int main()
{
int m = 25;
int n = 100;
printf("m is %d, n is %d\n", m, n);
swap(&m, &n); //calling a function
printf("m is %d, n is %d\n", m, n);
return 0;
}
void swap (int *a, int *b) //function implementation
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
problem is why not allowed this one in the above program
void swap (int, int); //function declaration
and give the error
error:
conflicting types for ‘swap’
void swap (int *a, int *b) //function implementation
but in book example allowed
void swap (int *a, int *b);
This here before main() is called function signature that should match function declaration
below.
void swap (int *a, int *b){
...
}
But the same function signature can be written as
void swap (int *, int *);
And not
void swap (int , int ); //This will result in type mismatch
I guess this is what you are asking.
NOTE: Forward declaration is important here which lets you declare first and define later helps maintain code readability.
So I'm new to C, I'm trying to make procedure to swap value of 2 variables.
When I run this the swap didn't work.
#include <stdio.h>
#include <stdlib.h>
void swap(int A,int B)
{
A = A + B;
B = A - B;
A = A - B;
}
int main(void){
int num1,num2;
printf("insert first number :\n");
scanf("%d",&num1);
printf("insert second number :\n");
scanf("%d",&num2);
swap(num1,num2);
printf("%d %d\n",num1,num2);
return 0;
}
That is because arguments are passed by value and modifying them in callee won't affect caller's local variables. Use pointers to modify ones.
#include <stdio.h>
#include <stdlib.h>
void swap(int* A,int* B)
{
*A = *A + *B;
*B = *A - *B;
*A = *A - *B;
}
int main(void){
int num1=0,num2=0; /* initialize for in case scanf() fails */
printf("insert first number :\n");
scanf("%d",&num1);
printf("insert second number :\n");
scanf("%d",&num2);
swap(&num1,&num2);
printf("%d %d\n",num1,num2);
return 0;
}
It didn't work because when you call the procedure, it is made a copy of the arguments to the new scope.
The right way is with the address of the variables.
Change to:
swap(&num1,&num2);
and
void swap(int *A,int *B)
{
*A = *A + *B;
*B = *A - *B;
*A = *A - *B;
}
This code is working but its not exactly what I want. Is anyone have any idea how to make it correct and without q sort?. The idea is to understand how to use pointers.
The three numbers should be random between -3 and 12. The code below is something similar, and the closest I have found. Any help would be much appreciated. Thanks in advance!!.
#include <stdio.h>
#include <stdlib.h>
//functions
int compare(const void *a, const void *b)
{
const int *ia = a;
const int *ib = b;
if (*ia < *ib)
return -1;
else if (*ia > *ib)
return +1;
return 0;
}
//qsort function
void sort3(int *a, int *b, int *c)
{
int temp[3];
temp[0] = *a;
temp[1] = *b;
temp[2] = *c;
qsort(temp, 3, sizeof(int), &compare);
*a = temp[0];
*b = temp[1];
*c = temp[2];
}
//random function
int rand_int(int a, int b)
{
return rand()%(b-a+1)+a;
}
int main(void)
{
//declaration of variables
int a,b,c;
int rand_int(int a, int b);
srand(time(0));
a = rand_int(-3,12);
b = rand_int(-3,12);
c = rand_int(-3,12);
printf("%i %i %i\n", a, b, c);
sort3(&a, &b, &c);
printf("%i %i %i\n", a, b, c);
return 0;
}
You don't need the compare() function if you don't want to use qsort().
You can rewrite sort3() like this:
void compare_and_swap(int *a, int *b) {
int t;
if (*a > *b) {
t = *a;
*a = *b;
*b = t;
}
}
void sort3(int *a, int *b, int *c) {
compare_and_swap(a, b);
compare_and_swap(a, c);
compare_and_swap(b, c);
}
This is actually a "bubble sort".
This is a lot of trouble to go for to sort 3 integers. Use if statements.
If the goal is actually to understand pointers, they seem intimidating but they're not so bad. Basically, they're a number that happens to be an address. You can manipulate like them numbers, but if you dereference them (with *), you can get the value there. This cuts both ways, though, because there's not much stopping you from dereferencing a value - which probably crashes your program (or more scarily, maybe not).
As long as you keep in mind what's an address and what's a value, you should be OK.