I'm trying to have some practice with C using Xcode, but got stock with some error.
The code is as follows:
#include <stdio.h>
#include <stdlib.h>
/* move previous elements down until insertion point reached */
void shift_element (unsigned int i ) {
int ivalue;
// guard against going outside array
for (ivalue = arr[i]; i && arr[i-1] > ivalue; i--) {
arr[i] =arr[i-1]; // move element down
arr[i] = ivalue; // insert element
}
}
int main(int argc, const char * argv[]) {
unsigned int arr[5] = {2,4,5,3,6};
shift_element(3);
// print arr
int i;
for (i=0;i < (sizeof (arr) /sizeof (arr[0]));i++) {
printf("%d\n",arr[i]);
}
return 0;
}
But it results in an error saying 'use of undeclared identifier 'arr''
I searched previous questions with the same subject but could not find a proper answer that would solve my problem.
I would be so happy if somebody can help.
Cheers
The arr variable isn't in scope of the shift function. You have to pass it in as a parameter.
You forgot to declare your 'arr'.
Here is a very good answer explaining the various way do to that : How to initialize all members of an array to the same value?
EDIT : Didn't see you declared it in the function below. As the other answer says, you have to pass it as a parameter tho.
Your problem lies in variable accessibility. When you define a variable in the main function it is only accessible in the function in which it was defined. You to try access the array in the shift_elements function which is causing your issue.
To fix this you can either make the arr variable global or pass it in as an argument to your shift_elements(function). I coded a quick correction doing the later because its good practice to avoid global variables when possible.
#include <stdio.h>
#include <stdlib.h>
/* move previous elements down until insertion point reached */
void shift_element (unsigned int i, int[] arr) {
int ivalue;
// guard against going outside array
for (ivalue = arr[i]; i && arr[i-1] > ivalue; i--) {
arr[i] =arr[i-1]; // move element down
arr[i] = ivalue; // insert element
}
}
int main(int argc, const char * argv[]) {
unsigned int arr[5] = {2,4,5,3,6};
shift_element(3, arr);
// print arr
int i;
for (i=0;i < (sizeof (arr) /sizeof (arr[0]));i++) {
printf("%d\n",arr[i]);
}
return 0;
}
For more information on types of variables look here: http://www.mathcs.emory.edu/~cheung/Courses/255/Syllabus/1-C-intro/kinds-vars.html
Just to share with those future possible readers, the correct code would be:
#include <stdio.h>
#include <stdlib.h>
/* move previous elements down until insertion point reached */
void shift_element (unsigned int i, unsigned int *arr ) {
int ivalue;
// guard against going outside array
for (ivalue = arr[i]; i && arr[i-1] > ivalue; i--)
arr[i] = arr[i-1]; // move element down
arr[i] = ivalue; // insert element
}
int main(int argc, const char * argv[]) {
unsigned int arr[5] = {2,4,5,3,6};
// print arr
int i;
for (i=0;i < (sizeof (arr) /sizeof (arr[0]));i++) {
printf("%d\n",arr[i]);
}
shift_element(3, arr);
// print arr
for (i=0;i < (sizeof (arr) /sizeof (arr[0]));i++) {
printf("%d\n",arr[i]);
}
return 0;
}
Related
I am trying to make a program that first creates an array in another function, returns it and then calls another function that shuffles the contents of the array and returns it. However I am struggling to do this in C since I do not quite understand the array pointer system that has to be used here.
So far my code doesnt return the values 1-20 from makeArray() but instead returns an array full of 0s and I have a feeling it has to do with the c's array pointer system.
Any help would greatly be appreciated! Thank you in advance
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int arrShuffle();
int arrShuffle(int * arr) {
int arr[21];
// shuffle array
for(int j=0; j<20; j++) {
int randInd = (rand() % 20) + 1;
int temp = arr[j];
arr[j] = arr[randInd];
arr[randInd] = temp;
}
return arr;
}
int makeArray() {
int arr[21];
// make array of 1-20
for(int i=0; i < 20; i++) {
arr[i] = i + 1;
}
return arr;
}
void main() {
int *orgArr;
int *modArr;
srand(time(NULL));
orgArr = makeArray();
for(int i=0; i < 20; i++) {
printf("OrgArr: %d\n", orgArr);
}
modArr = arrShuffle(orgArr);
}
You cannot use variables with automatic storage (aka local ones). You must allocate the array so the memory remains valid after the function ends:
int* makeArray() {
int *arr = calloc(21, sizeof *a);
// make array of 1-20
for(int i=0; i < 20; i++) {
arr[i] = i + 1;
}
return arr;
}
Remember to release the array when it is no longer used:
int main() {
int *orgArr;
...
orgArr = makeArray();
...
free(orgArr);
}
As tstanisl pointed out in their answer, a possible solution is to use dynamic memory allocation. My answer, instead, will give you yet another solution: using an array passed by the caller.
NOTE: both solutions are valid and their usefulness depends on the specific needs of your program. There's no "right" universal solution.
void makeArray(int arr[], size_t len) {
for (size_t i = 0; i < len; i += 1) {
arr[i] = (int) (i + 1);
}
}
void cloneAndModifyArray(const int orig[], int new[], size_t len) {
for (size_t i = 0; i < len; i += 1) {
new[i] = orig[i] * 2; // or some other modification
}
}
And you use it like this:
#define ARR_LEN (100)
int main(void) {
int arr[ARR_LEN];
makeArray(arr, ARR_LEN);
int modified_arr[ARR_LEN];
cloneAndModifyArray(arr, modified_arr, ARR_LEN);
return 0;
}
I have a problem with a rather big piece of code. Knowing myself, it's some kind of a silly mistake, or, more likely, lack of understanding of pointers. I really need some help, so if someone could look at it I would be so grateful! I'm going to explain it now.
It's a program for my programming class. The teacher gave us a number (N) and a letter (X) in a txt file, and wants us to create a structure with three fields(int, char and float), and then four functions:
function #1 takes the number N as an argument and dynamically allocates memory for an array of pointers to N structures. then it assigns values to the fields in the structures - int and char are set to random values, and the float field is set to the number of the structure. the function returns the address of the array.
function #2 takes the size of the created array (the number of pointers in it) and a pointer to the array as arguments and deletes the array, freeing the memory.
function #3 takes the size of the created array and a pointer to the array as arguments, and then sorts the structures based on the int field, using bubble sort
function #4 searches through the structures and counts how many times the letter (X) is repeated in the char fields of the structures.
Here's the code with comments and errors. Please, can someone explain what am I doing wrong? To be honest I'm almost out of time, but I'm willing to stay up all night to understand and fix this.
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h>
struct Foo {
int fieldint;
char fieldchar;
float fieldfloat;
};
Foo *initialize(int N);
int sort(int N, Foo *tablica);
int count(int N, Foo *tablica, char*X);
int deleting(int N, Foo **tablica);
int main () {
//this reads the number N and the letter to find from the .txt file:
FILE *file = fopen("inlab01.txt", "r");
int number;
char letter[1];
if (file == NULL) {
printf("Error opening file");
exit(-1);
}
while (fscanf(file, "%d%s", &number, letter) != EOF);
fclose(file);
//creating the array
//again, it's supposed to be an array of pointers to N structures:
Foo *arr[number];
*arr = initialize(number);
//sorting:
sort(number, *arr); //the program crashes at this function
//counting how many times the given letter appears:
//count(number, *arr, letter);
//we're supposed to print the first 20 of the structures
//this loop prints one structure and then the program crashes
for(int i=0;i<20;i++) {
printf("Structure %d:\nfield int:%d\nfield char:%c\nfield float:\f\n\n", i+1, arr[i]->fieldint, arr[i]->fieldchar, arr[i]->fieldfloat);
}
//deleting:
deleting(number, arr);
getch();
return 0;
}
Foo *initialize(int N) {
Foo **array;
array = (Foo **)malloc(sizeof(Foo) * N);
srand( time( NULL ) );
for(int i=0; i<N; i++) {
array[i] = (Foo*)malloc(sizeof(Foo));
array[i] -> fieldint = rand(); //random number
array[i] -> fieldchar = ( char )( rand() % 24 ) + 65; //random letter
array[i] -> fieldfloat=i;
}
return *array;
}
int sort(int N, Foo *array) {
int temp;
for (int i=0;i<N;i++){
for (int j=N-1;j>=j;j--) {
if(array[j].fieldint < array[j-1].fieldint) {
temp = array[j-1].fieldint;
array[j-1].fieldint = array[j].fieldint;
array[j].fieldint = temp;
}
}
}
return 0;
}
int count(int N, Foo *array, char*X){
int counter = 0;
for(int i=0;i<N;i++) {
if (array[i].fieldchar == 'X') {
counter = counter+1;
}
}
return counter;
}
int deleting(int N, Foo **array) {
for (int i=0;i<N;i++) {
free(array[i]);
}
free(array);
return 0;
}
The whole thing compiles, but then the program crashes instead of doing anything, really.
Please help.
struct Foo
{
int fieldint;
char fieldchar;
float fieldfloat;
};
Foo **array;
array = (Foo **)malloc(sizeof(Foo) * N);
You are compiling this code in C++. You want to use a C compiler, and you have to change the code to the following:
struct Foo **array;
You would use struct Foo everywhere, and you don't need that cast. Or declare the structure with typedef
Secondly, Foo **array is for allocating a 2-dimensional array. The way you are allocating 2-D array is wrong. Besides, you only need a 1-dimensional array Foo arr[number]
for (int j=N-1;j>=j;j--)
Note you have an error in your sort function (j >= j) is always true. Fix the sort function, avoid allocating a 2-D array and you are done.
int sort(int N, struct Foo *array)
{
int temp, i, j;
for (i = 0; i< N; i++) {
for (j = i + 1; j < N; j++) {
if (array[i].fieldint > array[j].fieldint) {
temp = array[i].fieldint;
array[i].fieldint = array[j].fieldint;
array[j].fieldint = temp;
}
}
}
return 0;
}
int main()
{
srand((unsigned)time(NULL));
int number = 3;
struct Foo arr[number];
int i;
for (i = 0; i < number; i++) {
arr[i].fieldint = rand(); //random number
arr[i].fieldchar = 'A' + (char)(rand() % 26); //random letter
arr[i].fieldfloat = (float)i;
}
sort(number, arr);
for (i = 0; i < number; i++)
printf("Structure %d:\nfield int:%d\nfield char:%c\nfield float:%f\n\n",
i + 1, arr[i].fieldint, arr[i].fieldchar, arr[i].fieldfloat);
getch();
return 0;
}
Note that your sort function swaps fieldint but Foo has other members, you probably want to swap all members if your goal is to swap the object.
I want to return a dynamic array by reference from a void function.
I already searching 3 hours for the answer, couldn't find anything helpfull.
Here is my simplified code :
main()
{
int **a;
xxx(&a);
printf("%d\n\n", a[1]);
}
void xxx(int **a)
{
int i;
*a = (int*)malloc(5 * 4);
for (i = 0; i < 5; i++)
a[i] = i;
printf("%d\n\n", a[1]);
}
I just want to allocate dynamic array in the "xxx" Function and return it by reference to main, than I want to print it or use it for something else. Thanks in advance :)
edit
#include <stdio.h>
#include <stdlib.h>
#define MACROs
#define _CRT_SECURE_NO_WARNINGS
void xxx(int **a);
int main(void)
{
int *a;
xxx(&a);
printf("%d\n\n", a[1]);
}
void xxx(int **a)
{
int i;
*a = malloc(5 * sizeof(**a));
for (i = 0; i < 5; i++)
a[i] = i;
printf("%d\n\n", a[1]);
}
I have amended a few things and added some comments.
#include <stdio.h> // please inlcude relevant headers
#include <stdlib.h>
#define ELEM 5 // you can change the requirement with a single edit.
void xxx(int **a) // defined before called - otherwise declare a prototype
{
int i;
*a = malloc(ELEM * sizeof(int)); // do not use magic numbers, don't cast
if(*a == NULL) {
exit(1); // check memory allocation
}
for (i = 0; i < ELEM; i++) {
(*a)[i] = i; // index correctly
}
}
int main(void) // 21st century definition
{
int *a; // correct to single *
int i;
xxx(&a);
for (i = 0; i < ELEM; i++) { // show results afterwards
printf("%d ", a[i]);
}
printf("\n");
free(a); // for completeness
}
Program output:
0 1 2 3 4
In your main(), you need to have a pointer, not a pointer to pointer. change
int **a;
to
int *a;
and, inside the xxx(), change
a[i] = i;
to
(*a)[i] = i;
That said
Don't use magic numbers, rewrite your malloc statement like
*a = malloc(5 * sizeof(**a));
to be more robust. Also, for static counts, use #define MACROs.
Please see this discussion on why not to cast the return value of malloc() and family in C..
main() is not a valid signature for a hosted environment. You need to use int main(void), at least.
Ok guys so the thing that made it work is
a[i] = i;
to
(*a)[i] = i;
3 hours for such a simple answer.
Thank you very much everybody here.
Can some explain why it was the problem?
I'm trying to pass an initialized char pointer array to a function. I can't seem to figure out why the function will only print out the numeric digits of each element in the array.
Does anyone know how I can print each string element from the passed in pointer array?
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
void sort(char *);
int main()
{
char *states[4] = {"Florida", "Oregon", "California", "Georgia"};
sort(*states);
return 0;
}
void sort(char *states)
{
int x;
for (x = 0; x < 4; x++) {
printf("\nState: %d\n", states[x]); //only this will compile
//printf("\nState: %s\n", states[x]); //need to print this.
}
}
Your sort function must accept the array of pointers if you wish to print the contents of the array.
void sort (char *states[], size_t num_states) {
int x;
for (x = 0; x < num_states; ++x) {
printf("\nState: %s\n", states[x]); /* Note %s instead of %d */
}
}
And, you must pass the array to the function.
sort(states, 4);
You need to parse an array of pointers to char to sort (instead of just pointer to char).
As jhx pointed out, you need to pass the size of the array as well. You can use sizeof so as to not hard-coding 4. Also omit the array size when initialize it.
void sort( char *states[], int arr_size )
{
int x;
for (x = 0; x < arr_size; x++)
{
printf( "\nState: %s\n", states[x] );
}
}
int main()
{
char *states[] = {"Florida", "Oregon", "California", "Georgia"}; // array of pointers to char
sort( states, sizeof( states ) / sizeof( char * ) );
return 0;
}
You need to pass the char pointer array to the function:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
void sort(char *args[], int n);
int main()
{
char *states[4] = {"Florida", "Oregon", "California", "Georgia"};
sort(states, 4);
return 0;
}
void sort(char *states[], const int N)
{
int x;
for (x = 0; x < N; x++) {
printf("\nState: %s\n", states[x]);
}
}
The reason that only numeric values you are getting is that only pointer to first element of string states[0] of the array states is passed, i.e. you are passing &states[0][0]. So, the statement
printf("\nState: %d\n", states[x]);
will only print the numeric value of first 4 characters of string "Florida".
You need to pass the pointer to first element of array states, i.e. &states[0].
This can be done by changing the declarator of function sort to
void sort(char **, size_t size); // You need to pass the size of array too.
and call it as
sort(states, sizeof(states)/sizeof(char *));
You're sending states which is an array of pointers. So you need to send the base address of that array to the function
sort(*states);
And then receive it in an array of pointer only
void sort(char* states[])
{
int x;
for (x = 0; x < 4; x++) {
printf("\nState: %s\n", states[x]);
}
}
Hardcoding the size if also not a good idea, so better add another parameter size to the function call.
sort(states, sizeof(states)/sizeof(char*));
and later use that to iterate over the array
void sort(char* states[], int size)
{
int x;
for (x = 0; x < size; x++) {
printf("\nState: %s\n", states[x]);
}
}
#include <stdio.h>
#include <stdlib.h>
void array_tester(int *array);
int main(int argc,char *argv[])
{
int test[] = {1,1,1,1};
int print;
for(print = 0; print < sizeof(test) / sizeof(int); print++)
{
printf("%d\n",test[print] );
}
array_tester(test);
for(print = 0;print < sizeof(test)/sizeof(int);print++)
{
printf("%d\n",test[print] );
}
return EXIT_SUCCESS;
}
void array_tester(int array[])
{
int i ;
for(i = 0; i < sizeof(array) / sizeof(int); i++)
{
array[i] = i;
}
}
The problem is I want to modify the the array in the array_tester function but I'm unable to do so. What do I use inside sizeof()?
You have to manually pass the information about the size of the array.
void array_tester( int* array , int size ) ;
And then call it:
array_tester( test , sizeof(test)/sizeof(*test) ) ;
The reason behind this is that array passed to a function will decay to a pointer and the sizeof will return the size of pointer not the original array.