I'm trying to learn pointers in C, and here is some code I wrote to test it:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int m = 4;
int *n;
n = &m;
printf("%d\n",*n);
for (*n = 0; *n < 100; *n++){
printf("%d\n",*n);
}
}
As expected, that first part printed 4. But the loop did not go further than 4, and did not go to 100 as I tried to make it.
Along with the pointer notation fix suggested by others, I would write this example so that it prints m in the loop, instead of *n, so you can see that manipulating *n does have indeed an effect on the variable to which it points:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int *n, m = 4;
n = &m;
printf("%d\n", *n);
for (*n = 0; *n < 100; (*n)++)
{
printf("%d\n", m);
}
}
Related
I am using a for loop to walk through the elements of char array teste. Within this loop, I am using an int variable called stack_index, for some controls. The program below runs fine, see that, its result is the value of stack_index repeated 18 times (size of char array teste).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
size_t char_size (char* c) {
return strlen(c);
}
int main() {
char teste[] = "Este *teste* string";
size_t n = char_size(teste);
char stack[20];
int stack_index = 0;
for(int i; i < n; i++){
printf("%d", stack_index);
}
}
Result of program above:
0000000000000000000
But, when I add just the line stack_index-- inside the loop, the loop index breaks in some crazy way. See that the result of this program is the values -1, -2 and -3. This result is indicating that the for loop is running only 3 times (instead of 18). But why this is happening? Why subtracting (or adding) 1 from the stack_index variable at each iteration, is affecting the loop index variable i? This makes no sense to me, since the i variable is the index variable of the loop, not stack_index.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
size_t char_size (char* c) {
return strlen(c);
}
int main() {
char teste[] = "Este *teste* string";
size_t n = char_size(teste);
char stack[20];
int stack_index = 0;
for(int i; i < n; i++){
stack_index--;
printf("%d", stack_index);
}
}
Result of program above:
-1-2-3
#Some programmer dude comment answer the problem. I did not initialize the i variable with some initial value (like 0). This mistake was breaking the loop, not the stack_index-- line.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
size_t char_size (char* c) {
return strlen(c);
}
int main() {
char teste[] = "Este *teste* string";
size_t n = char_size(teste);
char stack[20];
int stack_index = 0;
for(int i = 0; i < n; i++){
stack_index--;
printf("%d", stack_index);
}
}
Result of program above:
-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19
I have written a basic loop:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
int a = atoi(argv[1]);
for (int i = a; i > 0; i = i - 7)
{
if (i < 7)
{
printf("%i", i);
}
}
}
I know how to print the end result, but I want to extract the result as an int so I can use it for calculations later on, how would I go about that?
If you declare i in the loop initializer, it'll be scoped to the for loop. So, declare it before the for loop, then assign it in the initializer:
int i;
for (i = a; i > 0; i = i - 7) {
// ...
}
printf("%i\n", i);
This question already has answers here:
Why is it safer to use sizeof(*pointer) in malloc
(3 answers)
What happens if I use malloc with the wrong size?
(4 answers)
Closed 2 years ago.
Here is my code with the print statement followed by its output.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int *myF(int a[],int s, int n);
int *myFunc(int x[],int size,int nnum) {
int i;
size += 1;
int *y = malloc(size);
for(i=0;i<size;i++) {
if(i==0)
*y = nnum;
else {
*(y+i) = x[i-1];
printf(" %d",*(y+i)); // <-- ***THIS THING RIGHT HERE***
}
}
return y;
}
int main (int argc, char *argv[]) {
int i;
int x[7] = {1,2,3,4,5,6,7};
int *P = myFunc(x,7,12);
for(i=0;i<8;i++) {
if(i==0) printf("\n");
printf(" %d",*(P+i));
}
return 0;
}
OUTPUT:
1 2 3 4 5 6 7
12 1 2 3 4 5 6 7
(The second matrix is what I want the code to output)
Here is my code without the print statement followed by its output.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int *myF(int a[],int s, int n);
int *myFunc(int x[],int size,int nnum) {
int i;
size += 1;
int *y = malloc(size);
for(i=0;i<size;i++) {
if(i==0)
*y = nnum;
else {
*(y+i) = x[i-1];
// printf(" %d",*(y+i)); <-- ***THIS THING RIGHT HERE*** commented out
}
}
return y;
}
int main (int argc, char *argv[]) {
int i;
int x[7] = {1,2,3,4,5,6,7};
int *P = myFunc(x,7,12);
for(i=0;i<8;i++) {
if(i==0) printf("\n");
printf(" %d",*(P+i));
}
return 0;
}
OUTPUT:
12 1 2 3 4 5 83 0
(This is not what I want...)
Can somebody please explain where this code is pulling 83 and 0 for the last two elements in the array just because I chose to include or exclude a random print statement?
Any help would be greatly appreciated because I can't understand how C is pulling numbers out of thin air like this.
Your malloc size is not correct and causes undefined behavior.
The actual memory size is the length of array * size of array type.
The printf in main is actually printing something random in the memory.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int *myF(int a[],int s, int n);
int *myFunc(int x[],int size,int nnum) {
int i;
size += 1;
//int *y = malloc(size * sizeof(int) );
int *y = malloc(size );
for(i=0;i<size;i++) {
if(i==0)
*y = nnum;
else {
*(y+i) = x[i-1];
printf(" %d",*(y+i)); // <-- ***THIS THING RIGHT HERE***
}
}
return y;
}
int main (int argc, char *argv[]) {
int i;
int x[7] = {1,2,3,4,5,6,7};
int *P = myFunc(x,7,12);
for(i=0;i<8;i++) {
if(i==0) printf("\n");
printf(" %d",*(P+i));
}
free(P);
return 0;
}
If you're interesting in why printf changed the behavior, this post has in-depth explanation.
Also don't forget to free P in the end.
I have a problem I can't figure out. I wrote this code to shuffle the elements of an array:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
const char *array[]={"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
int main(int argc, char **argv)
{
int i, tmp, randomize, size;
size = sizeof(array)/sizeof(*array);
srand(time(NULL));
for(i=size;i>0;i--){
randomize=0+(rand()%size);
tmp=(int)array[i];
array[i]=array[randomize];
array[randomize]=(char*)tmp;
}
for(i=0;i<size;i++)
printf("%s", array[i]);
return 0;
}
When I run the program, this is the iutput:
azlngiwexbv(null)uscphqjyrodmtk
I can't understand why the pointer is sometimes null and I can't understand why, changing the source code in this way:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char **argv)
{
char *array[]={"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
int i, tmp, randomize, size;
size = sizeof(array)/sizeof(*array);
srand(time(NULL));
for(i=size;i>0;i--){
randomize=0+(rand()%size);
tmp=(int)array[i];
array[i]=array[randomize];
array[randomize]=(char*)tmp;
}
for(i=0;i<size;i++)
printf("%s", array[i]);
return 0;
}
Everything works fine.
Thanks.
Start loop from size-1, you are pointing out of array in array[size] (first loop iteration).
for (i=size-1; i>=0; i--)
You should avoid casting whenever possible, and it is rarely necessary to do so.
Unless you plan on using argc and argv[], use the simpler form for main(): int main(void). This will remove some compiler warnings, and you should have these enabled; remove all warnings emitted by your compiler.
You cast a pointer to char to int to store it in tmp, and then you cast tmp back to (char *). Just declare tmp as a pointer to char to start with. The first loop counts down from size to 0; this is out of array bounds to start, but why not just use the conventional loop construction: for (i = 0; i < size; i++)? Also, you should consider using size_t for array indices; it is an unsigned integer type guaranteed to be able to hold any array index, and is also the type returned by the sizeof operator.
Further, in your first version you have declared array as an array of pointers to const chars. You can do this, but you need the temporary storage variable tmp to agree with the const type qualifier.
Here is your code with the above changes. There are no casts, it compiles without warnings, and it works.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
const char *array[] = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
const char *tmp;
size_t i, size;
int randomize;
size = sizeof(array) / sizeof(*array);
srand(time(NULL));
for(i = 0; i < size; i++){
randomize = (rand() % size);
tmp = array[i];
array[i] = array[randomize];
array[randomize] = tmp;
}
for(i = 0; i < size; i++)
printf("%s", array[i]);
putchar('\n');
return 0;
}
I try to implement a function meant to roll a dice a certain amount of time.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int * rollDice(int len) //len = times the dice is rolled.
{
int ints[len];
int i = len-1;
while(i>0)
{
ints[i--] = (rand()%6)+1;
}
return ints;
}
int main(int argc, const char * argv[])
{
int * ints = rollDice(10);
for(int i =0; i<10; i+=1)
{
printf("%d ",*(ints+i));
}
return 0;
}
Program always prints this, is my conception of pointers false ?
104 0 0 0 1919706998 2036950640 1667723631 1836545636 16 48
You cannot do this
return ints;
It's declared on the stack. You need to either pass it in with enough memory or allocated the memory in the function using malloc and pass it back.
int * rollDice(int len) //len = times the dice is rolled.
{
int *ints = malloc(sizeof(int) * len);
int i = len-1;
while(i>0)
{
ints[i--] = (rand()%6)+1;
}
return ints;
}
Harry's answer is right; you can't return the address of a local variable. That variable is destroyed as soon as the function returns.
Instead of having to allocate memory in the function, just pass the array to be filled into the function:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NUM_DICE 10
void rollDice(int *dice, int num_dice)
{
int i;
for (i = 0; i < num_dice; i++) {
dice[i] = (rand() % 6) + 1;
}
}
int main(int argc, const char * argv[])
{
int dice[NUM_DICE];
srand(time()); /* Don't forget this! */
rollDice(&dice, NUM_DICE);
for(int i = 0; i < NUM_DICE; i++)
{
printf("%d ", dice[i]); /* Easier to use brackets than pointer arithmetic. */
}
return 0;
}