I am doing an exercise where the task is to fix swap_pointer().
Two string should be swapped.
s1 = "I should print second.";
s2 = "I should print first.";
My work so far:
#include <stdio.h>
void swap_nums(int *, int *);
void swap_pointers(char *x, char *y);
int main(void) {
int a = 3, b = 4;
char *s1, *s2;
swap_nums(&a, &b);
printf("a is %d\n", a);
printf("b is %d\n", b);
s1 = "I should be printed second.";
s2 = "I should be printed first.";
/* swap_pointers(s1, s2); */
printf("s1 is %s\n", s1);
printf("s2 is %s\n", s2);
return 0;
}
void swap_nums(int *x, int *y) {
int tmp;
tmp = *x;
*x = *y;
*y = tmp;
}
void swap_pointers(char *x, char *y) {
char tmp;
tmp = *x;
*x = *y;
*y = tmp;
}
I think that not appending & to s1 and s2 before I pass them to the function for swap_pointers is the error?
If anyone can fix my issue here, please don't give the whole solution! I want to use what you give me as a tool to fix it by my own. If I really can't fix it by my own I will adress this later.
Ty in advance!
Let's at first consider this code snippet
int a = 3, b = 4;
swap_nums(&a, &b);
To swap the objects a and b you need to pass then to the function swap_nums by reference through pointers to them. Thus within the function dereferencing the pointers we can get a direct access to original objects and change their values.
void swap_nums(int *x, int *y) {
int tmp;
tmp = *x;
*x = *y;
*y = tmp;
}
The same we need to do with the variables s1 and s2. That is we need to pass them to the function swap_pointers by reference through pointers to them.
So you need to write
swap_ponters( &s1, &s2 );
and the function will be declared and defined like
void swap_ponters(char **x, char **y)
{
char *tmp = *x;
*x = *y;
*y = tmp;
}
In general if you have two objects like
T a;
T b;
where T is some type specifier then to change the objects in a function you need to pass them to the function by reference through pointers to them. So the declaration of the function swap will look like
void swap( T *a, T *b );
and the function will be called like
swap( &a, &b );
In your program a and b has the type int, that is T is an alias for the type int.
typedef int T;
T a = 3, b = 4;
so the function declaration will look like
void swap_nums( T *x, T *y );
For the variables s1 and s2 you can write
typedef char *T;
T s1, s2;
and again the function declaration will look like
void swap_pointers( T *x, T *y );
and the function will be called like
swap_pointers( &s1, &s2 );
As in this case T is an alias for the type char * then the function declaration can be rewritten like
void swap_pointers( char * *x, char * *y );
Your pass the pointers to the first characters of two null-terminated strings to the swap_pointers function.
Inside the function, when you use e.g. *x it's the same as x[0].
So you're swapping the first character of x with the first character of y.
If you want to switch pointers, you need to emulate pass-by-reference like you do with swap_nums, and pass pointers to the pointers, i.e. char **. And use the pointer-to operator & in the call.
So it should be
void swap_ponters(char **x, char **y);
and
swap_pointers(&s1, &s2);
Related
I need to create a swap function that takes 2 addresses as input and swaps them regardless what type they point to. Here's my swap function:
void swap(void* x,void* y){
void* temp=x;
x=y;
y=temp;
}
When I use it with integers it works fine and swaps them properly, but using strings the addresses seems to swap inside the function but when I try to call them from outside the function I notice they didn't change at all.
Here's my full code and the resulting output.
printf("before %s %s\n",(char*)array[i],(char*)array[j] );
swap(array[i], array[j]);
printf("after %s %s\n",(char*)array[i],(char*)array[j] );
I casted everything to string to understand what was wrong with them
void swap(void* x,void* y){
printf(" after IN %s %s\n",(char*)x,(char*)y );
void* temp=x;
x=y;
y=temp;
printf(" after IN %s %s\n",(char*)x,(char*)y );
}
OUTPUT
before fannullone falafel
after IN fannullone falafel
after IN falafel fannullone
after fannullone falafel
To swap two objects in a function you need to pass them to the function by reference.
In C passing by reference means passing objects indirectly through pointers to them. So dereferencing the pointers the function gets a direct access to the original objects and can change them.
So for objects of the type void * the function parameters will have the type void **. The function will look like
void swap( void **x, void **y )
{
void *temp = *x;
*x = *y;
*y = temp;
}
Here is a demonstration program.
#include <stdio.h>
void swap( void **x, void **y )
{
void *temp = *x;
*x = *y;
*y = temp;
}
int main( void )
{
void *s1 = "Hello";
void *s2 = "World";
printf( "s1 = %s, s2 = %s\n", ( char * )s1, ( char * )s2 );
swap( &s1, &s2 );
printf( "s1 = %s, s2 = %s\n", ( char * )s1, ( char * )s2 );
}
The program output is
s1 = Hello, s2 = World
s1 = World, s2 = Hello
It cannot be done with a function because there is no generic pointer to pointer in C. For example the type void** is not compatible with char**. Technically, those pointers could have different representation what would disallow dereferencing after casting or using memcpy().
Therefore, it is better to use a macro:
#define SWAP(a, b) \
do { \
void *tmp = *(a); \
*(a) = *(b); \
*(b) = tmp; \
} while (0)
I am trying to swap 2 entries in an array of strings, but my swap function doesn't swap when called.
swap(char*, char*);
int main() {
char *ptsr[2] = { "x", "y" };
swap(ptsr[0], ptsr[1]);
}
swap(char *t1, char *t2) {
char *t;
t = t1;
t1 = t2;
t2 = t;
}
Can someone identify and explain my mistake?
C is strictly pass by value. You pass the values of ptsr[0] and pstr[1] to swap. It swaps where it keeps those two values, but that has no effect on the calling function. Consider:
swap (int v1, int v2)
{
int t;
t = v1;
v1 = v2;
v2 = t;
}
This is the same as your swap function, just using int instead. It should be pretty clear that if you call swap(1,2);, the swap function just puts the 2 where it was storing the 1 and vice versa, but that has no effect on anything in the caller.
Same if you do this:
int i = 2;
int j = 3;
swap(i,j);
Since all you passed to swap is the values 2 and 3, it cannot affect the values of i and j by any means.
And same with your swap function if you do this:
char* j = "hello";
char* k = "world";
swap(j,k);
The function receives "hello" and "world" and swaps where it stores those two pointers. This has no effect on j or k in the caller.
C is strictly pass by value. Whatever parameters you pass to a function, the function only receives the values of.
The function in the question only swaps the values of its argument. The arguments are copies of the array elements, so the swap function has no effect.
To swap the pointers in the array, you must pass their addresses and change the prototype of the swap function:
#include <stdio.h>
void swap(char **t1, char **t2) {
char *t;
t = *t1;
*t1 = *t2;
*t2 = t;
}
int main() {
char *ptsr[2] = { "x", "y" };
swap(&ptsr[0], &ptsr[1]);
printf("pstr: { \"%s\", \"%s\" }\n", pstr[0], pstr[1]);
return 0;
}
Functions accept their arguments by value.
That is the function swap (for which you forgot to specify the return type void)
void swap(char *t1, char *t2) {
char *t;
t = t1;
t1 = t2;
t2 = t;
}
deals with copies of values of the expressions ptsr[0] and ptsr[1]. Chamging the copies does not influence on the original pointers.
You may imagine the function definition and its call the following way
swap(ptsr[0], ptsr[1]);
//...
void swap( /*char *t1, char *t2*/) {
char *t1 = ptsr[0], *t2 = ptsr[1];
char *t;
t = t1;
t1 = t2;
t2 = t;
}
As you can see the variables and ptsr[0] and ptsr[1] were not be changed.
To change an object (that in particularly can have a pointer type) in a function you need to pass it to the function by reference.
In C passing by reference means passing an object indirectly through a pointer to it.
So the function swap will look like
void swap(char **t1, char **t2) {
char *t;
t = *t1;
*t1 = *t2;
*t2 = t;
}
and the function must be called .like
swap( &ptsr[0], &ptsr[1] );
Or as the same
swap(ptsr, ptsr + 1);
Dereferencing the pointers to pointers t1 and t2 the function gets a direct access to the original pointer ptsr[0] and ptsr[1] swapping their values.
Anyone know how to return 3 char values from a function to the main part? The three chars have to be input by the user and made into a pyramid. I have been told to use pointers but don't understand how to do it and keep getting errors. These 3 characters then have to be used in the main function to make a pyramid shape.
To expand on my comment, there are basically two ways I would recommend solving this problem, of which the first comes in two variants (depending on use-case and requirements).
Pass an array as argument to the function, and have it filled in. This comes with two variants depending on what is needed:
Just use an ordinary array
void doSomething(char *array)
{
array[0] = 'A';
array[1] = 'B';
array[2] = 'C';
}
Call like
char array[3];
doSomething(array);
printf("First character is '%c'\n", array[0]);
The second variant is basically the same as above, but treats the array as a (null-terminated) string:
void doSomething(char *array)
{
strcpy(array, "ABC");
}
Call like
char array[4]; // One extra for terminator
doSomething(array);
printf("String is '%s'\n", array);
The second way to return multiple values is through the use of structures:
struct Data
{
char a;
char b;
char c;
};
struct Data doSomething(void)
{
struct Data data;
data.a = 'A';
data.b = 'B';
data.c = 'C';
// or struct Data data = { 'A', 'B', 'C' };
return data;
}
Call like
struct Data data = doSomething();
printf("First character is '%c'\n", data.a);
I write an example of pointers, I hope it's useful:
main(){
int a,b,c;
doSomething(&a,&b,&c);
}
void doSomething(int *x, int *y, int *z){
//example
*x = 5;
*y = 7;
*z = 10;
}
Hi please kindly explain to me why is the code generating an error,
#include<stdio.h>
int main(){
char ***x;
char **q = *x;
char **(*c) = x;
char ***d = &q;
char ***p = "asdasd";
x=p;
printf("d:%s\n",d);
printf("q:%s\n",q);
printf("x:%s\n",x);
return 0;
}
Output:
1
Segmentation fault
Hi Thanks for the replys so if I init x, i still got an Segmentation fault on
printf("q:%s\n",q);
the output and code is shown below, please kindly advise why is d:1231 instead of 1231123124 and why x=p only change the value of x instead of all (x, q, d)
int main(){
char ***x = "1231123124";
char **q = *x;
char **(*c) = x;
char ***d = &q;
char ***p = "asdasd";
x=p;
printf("p:%s\n",p);
printf("d:%s\n",d);
// printf("q:%s\n",q);
printf("x:%s\n",x);
printf("c:%s\n",c);
return 0;
}
Output:
p:asdasd
d:1231
x:asdasd
c:1231123124
char **q = *x;
Here you are dereferencing an uninitialized pointer.
It's undefined behaviour, in this case it usually results a segfault (in practice your code will try to dereference some random memory location, or NULL if your compiler initializes local variables (this is typical for debug/non-optimized builds)).
These are type errors.
printf("d:%s\n",d); // d is char***, not char*
printf("q:%s\n",q); // q is char**, not char*
printf("x:%s\n",x); // x is char***, not char*
The %s specifier expects a char * argument, or possibly void *, const char *, etc., but never a char ** or char ***.
I have written code to swap strings, but I am not able to swap. What is the problem and how can I solve it by using a function, swap?
#include <stdio.h>
void swap( char*,char*);
int main()
{
char *ptr[2] = {"hello", "morning"};
swap(ptr[0], ptr[1]);
printf("%s %s", ptr[0], ptr[1]);
return 0;
}
void swap(char *t1, char*t2)
{
char *t;
t = t1;
t1 = t2;
t2 = t;
}
I also tried to pass (&ptr[0], &ptr[1]), but here it shows a segmentation fault. Also I made a char, *p1 = ptr[0], char *p1 = ptr[1], and then passes &p1, and &p2 to swap, but still I get a segmentation fault.
C function arguments are pass-by-value. You're passing the value of addresses to your swap function, and expecting those values, the addresses, to change. But only the copies of the addresses in your swap function change.
To change the actual passed-in addressed, you'll need an aditional level of reference:
void swap(char **t1, char **t2)
{
char *t;
t = *t1;
*t1= *t2;
*t2 = t;
}
And call this swap like so: swap(&ptr[0], &ptr[1]);
You need to pass in pointers to the pointers of the char arrays in order to switch them. By doing that you can swap the values of those pointers instead. (Which are the actual arrays.)
#include<stdio.h>
void swap( char**,char**);
int main()
{
char *ptr[2] = {"hello","mornig"};
swap(&ptr[0], &ptr[1]);
printf("%s %s",ptr[0], ptr[1]);
return 0;
}
void swap( char **t1,char **t2)
{
char *t;
t = *t1;
*t1 = *t2;
*t2 =t;
}
You need to pass pointers to your strings to swap them (char**). Otherwise the changes you do will be local to the swap function.
void swap( char **t1,char **t2)
{
char *t;
t = *t1;
*t1 = *t2;
*t2 =t;
}
int main()
{
char *ptr[2] = {"hello","mornig"};
swap(&ptr[0], &ptr[1]);
printf("%s %s",ptr[0],ptr[1]);
return 0;
}
char *ptr[2] = {"hello","mornig"}; - This statement means you are allocating an array of size 2 which is going to store a address of two strings(ie char *). Now the two strings you are giving will be in text segment which is a read only data. If we tries to modify it, which will leads to crash(sgmentation fault).
So if you call swap(&ptr[0], &ptr[1]) leads to a crash. because you are trying to write the charcter m in the first read only string h. Write is not possible to the string which is in text segment.
If you want to simply swap a string you can call the function as swap(&ptr[0], &ptr[1]), which is equivalent to swap((ptr + 0),(ptr + 1));.
And change the swap function as below
void swap( char **t1,char **t2)
{
char *t;
t = *t1;
*t1 = *t2;
*t2 =t;
}
Here we are just swapping the address of the string stored in the array pointer ptr.