Int variable subtraction affecting for loop index - c

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

Related

Is there a way to initialize all int array elements to zero except for loop

Is there a way to initialize all int array elements to zero except a for loop where we loop through to set values to zero. Here the size of array is decided by input of user.
#include <stdio.h>
int main() {
int num_cases = 0;
scanf("%d", & num_cases);
int arr_counter[num_cases];
for (int x = 0; x < num_cases; x++) {
arr_counter[x] = 0;
}
}
Yes, you can do that in multiple ways under C standard. For example:
memset() [Stack and Heap]
calloc() [Heap Only]
loops, e.g., do-while, while and for [Stack and Heap]
{ } [Stack Only]
1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int arr[10];
size_t len_arr = sizeof(arr) / sizeof(*arr);
memset(arr, 0, sizeof(arr));
for(size_t i = 0; i < len_arr; i++)
printf("%d\n", arr[i]);
return EXIT_SUCCESS;
}
Note: We can use memset() to set all values as 0 or -1 for integral data types also. It will not work if we use it to set as other values. The reason is simple, memset() works byte by byte.
2
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int *arr = calloc(10, sizeof(int));
if(!arr)
{
fprintf(stderr, "bad ptr");
return EXIT_FAILURE;
}
for(size_t i = 0; i < 10; i++)
printf("%d\n", arr[i]);
free(arr);
return EXIT_SUCCESS;
}
Note: You need to keep track of arr maximum length.
Note: malloc() leaves garbage value in your pointer, whereas calloc() uses memset() to initialize them to 0.
Note: You need to free the heap allocated resource.
3
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int arr[10];
size_t len_arr = sizeof(arr) / sizeof(*arr);
for(size_t i = 0; i < len_arr; i++)
arr[i] = 0;
for(size_t i = 0; i < len_arr; i++)
printf("%d\n", arr[i]);
return EXIT_SUCCESS;
}
Note: You can use any of your favorite loop.
4
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int arr[10] = {};
size_t len_arr = sizeof(arr) / sizeof(*arr);
for(size_t i = 0; i < len_arr; i++)
printf("%d\n", arr[i]);
return EXIT_SUCCESS;
}
Use calloc function available in stdlib.h
#include<stdio.h>
#include<stdlib.h>
int main(){
int num_cases;
scanf("%d", &num_cases);
int* arr = (int*)calloc(num_cases,sizeof(int));
return 0;
}
To initialize each element of Array you have two approaches:
If you are going for static memory allocation, you can initialize it like this:
int arr[10] = {};
If you are going for dynamic memory allocation, you can use calloc function.
int *arr = (int) calloc(numberOfElementsInArray,sizeOfEachElement);
In your case, it would be like:
int *arr_counter = (int*) calloc(num_cases,sizeof(int));
NOTE: You need to include malloc.h header file to use calloc function.

Is this C code acceptable for finding the no.of occurences for each integer in an array? Which I tried for short code aim

If this has any error, kindly mention it. Because I may figure out some future consequences
#include<stdio.h>
int main()
{
int a[]={1,2,3,4,5,5,4,3,4,5},count[10]={0},i;
for(i=0;i<sizeof(a)/sizeof(a[0]);i++)
{
int x;
x=a[i];
count[x]=count[x]+1;
}
for(i=0;i<sizeof(count)/sizeof(count[0]);i++)
{
if(count[i]!=0)
{
printf("\n %d:%d",i,count[i]);
}
}
}
Generally? No. In this specific case? Maybe.
Instead of sizeof(a)/sizeof(a[0]), use a macro to get the array size.
Dont declare/initialize a loop variable and two arrays in one line.
You will get out of bounds issues as soon as a contains a number that is bigger than the length of count - 1 or smaller than 0.
I would do something like the following:
#include <stdio.h>
#include <string.h>
#define ARRAY_COUNT(array) (sizeof(array)/sizeof(array[0]))
void GetCountOfNumberInArray(int intArray[],
unsigned int intArraySize,
int numbersToCount[],
unsigned int numberCount[],
unsigned int numbersToCountSize){
memset(numberCount, 0, numbersToCountSize * sizeof(numbersToCountSize));
unsigned int count = 0;
for(unsigned int i = 0; i < intArraySize; i++){
for(int j = 0; j < numbersToCountSize; j++){
if(numbersToCount[j] == intArray[i]){
numberCount[j]++;
break;
}
}
}
}
int main(int argc, char *argv[]){
int intArray[] = {1,2,3,4,5,5,4,3,2,1};
int numbersToCount[] = {1,2,3,4,5,6,7,8,9,10};
unsigned int numberCount[ARRAY_COUNT(numbersToCount)];
GetCountOfNumberInArray(intArray,
ARRAY_COUNT(intArray),
numbersToCount,
numberCount,
ARRAY_COUNT(numbersToCount));
for(unsigned int i = 0; i < ARRAY_COUNT(numbersToCount); i++){
printf("number %i appears %u times in the array\n", numbersToCount[i], numberCount[i]);
}
}
That way you get a universal function to count a set of numbers in an array that still works similar to your original solution.

Why is the code printing me only the value of the last pointer in the array of pointers to a string?

Here is my code
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void main(){
char* a[5] = { "tomer","tomer","tomer","tomer","tomer" };
char t[] = "ppppr";
char* n = &t;
for (int i= 0;i < 3;i++) {
scanf(" %s",n);
a[i] = n;
}
for ( int j= 0;j < 3;j++) {
printf("%s\n", a[j]);
}
system("pause");
return 0;
}
What is the reason this outputs three times the last vlaue in the array?
Because you are allocating the memory for new string only once which is
char t[] = "ppppr";
BTW, there are other problems with in your code.
you are returning 0 from main but its return type is void instead of
int
you should do char* n = t; not &t

Null pointer using const instead of variable declaration

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;
}

Why does this for-loop with a pointer not go anywhere?

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);
}
}

Resources