I wish to get my code cleaner, the code can compile, but unfortunately there are still some
stuff showing minor problem about this following "error message"
how can I solve this ?
#include <stdlib.h>
#include <stdio.h>
int main(){
int arr0[] = {1,2,3,4,5};
int arr1[] = {2,2,2,2,2};
int arr2[] = {1,4,2,4,4};
int sizeArr0 = sizeof(arr0);
int sizeArr1 = sizeof(arr1);
int sizeArr2 = sizeof(arr2);
parseArray(arr0[0], sizeArr0);
parseArray(arr1[0], sizeArr1);
parseArray(arr2[0], sizeArr2);
}
int parseArray(int ch[], int sizeValue){
int sum;
for(int x = 0; x < ch; x++){
int ch[x];
if(x == 5){
sum += 5;
}
if (sum == 15){
return sum;
}
}
}
warning: implicit declaration of function ‘parseArray’ [-Wimplicit-function-declaration]
17 | parseArray(arr0[0], sizeArr0);
| ^~~~~~~~~~
test.c: In function ‘parseArray’:
test.c:30:22: warning: comparison between pointer and integer
30 | for(int x = 0; x < ch; x++){
You need to have a function definition or prototype before the function which calls it
int parseArray(int ch[], size_t sizeValue);
int main()
{
/* ... */
for(int x = 0; x < ch; x++){ makes no sense and I believe that an typo.
for(size_t x = 0; x < sizeValue; x++){
int sizeArr0 = sizeof(arr0); is giving you the size of the array in char not in element types. You need to divide it by the size of the elements. It should also have different type (size_t) size_t sizeArr0 = sizeof(arr0) / sizeof(arr0[0]);
All local function variables have to be initialized as they are not zeroed as global variables. int sum = 0;
You pass the first element to the array not the reference to the array parseArray(arr0, sizeArr0); or parseArray(&arr0[0], sizeArr0);
Related
In the book I am studying it says that if I pass a vector to a function, the name of the vector is always treated as a pointer.
In fact it's so.
But I can't understand why in the first function the const clause is allowed by the compiler, while in the second function (where I use pointers to search for the maximum value between the elements) no.
In the functions I would simply like to protect against the modification of the vector.
#include <stdio.h>
int find_largest(const int a[], int n);
int find_largest_with_pointer(const int *vettore, int n);
int main(void) {
int my_number[] = {5, 7, 90, 34, 12};
int n = sizeof(my_number) / sizeof(my_number[0]);
int *pmy_number = my_number;
printf("%d\n", find_largest(my_number, n));
printf("%d\n", find_largest(pmy_number, n));
printf("%d\n", find_largest_with_pointer(my_number, n));
printf("%d\n", find_largest_with_pointer(pmy_number, n));
return 0;
}
int find_largest(const int a[], int n) {
int i, max;
max = a[0];
for(i = 0; i < n; i++)
if(a[i] > max)
max = a[i];
return max;
}
int find_largest_with_pointer(const int *vettore, int n) {
int *i, max = *vettore;
for(i = vettore; i < vettore + n; i++)
if(*i > max)
max = *i;
return max;
}
Since vettore is a pointer to const int, you must make i have the same type.
const int *i;
int max = *vettore;
for(i = vettore; i < vettore + n; i++)
Short Version: Adding a const qualifier will address the compiler warning.
int find_largest_with_pointer(const int *vettore, int n) {
// int *i, max = *vettore;
const int *i ;
int max = *vettore;
...
}
Long Version:
In the second function, you use two variables. Expanding the code a little bit
int *i ;l
it max = a[0] ;
for (
i = vettore;
i < vettore + n;
i++
) { ... }
Note the line i = vettore, which will attempt to copy the 'const int * vettoreinto non-const 'int *i. This has the potential of allowing modification to the const vector (e.g. *i = 5), and the compiler complain:
c.c:33:11: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
for(i = vettore; i < vettore + n; i++)
Solution is simple: add const qualifier on const int *i. See above.
I have been trying to pass my array address to print array values in main function. But it is not working as it gives "Count by X.exe has stopped working". It also shows a warning message which says "function is returning address of local variables". I am not able to find the problems. It would be helpful if anyone finds pointer related problem of my code which is given below.
#include<stdio.h>
int * countBy(int x, int n)
{
int arr[n];
int count = x;
for(int i = 0; i < n; i++)
{
arr[i] = count;
count = count + x;
}
return arr;
}
int main()
{
int x = 2, n = 10;
int * prr;
prr = countBy(x, n);
for(int i = 0; i < 10; i++)
{
printf("%d ", prr[i]);
}
return 0;
}
You cannot return arrays in C. You would either need to create the array in the main function and pass it to the function or use dynamic allocation.
Passing an output array:
void countBy(int x, int n, int *arr)
{
int count = x;
for(int i = 0; i < n; i++) {
arr[i] = count;
count = count + x;
}
}
int main(void)
{
int x = 2, n = 10;
int arr[n];
countBy(x, n, arr);
}
Dynamic allocation:
int * countBy(int x, int n)
{
int *arr = malloc(n * sizeof(*arr));
int count = x;
for(int i = 0; i < n; i++) {
arr[i] = count;
count = count + x;
}
return arr;
}
int main(void)
{
int x = 2, n = 10;
int *prr;
prr = countBy(x, n);
free(prr); // Remember to use free to not cause memory leaks
}
The local variables have a lifetime which extends only inside the block in which it is defined. The moment the control goes outside the block in which the local variable is defined, the storage for the variable is no more allocated (not guaranteed). Therefore, using the memory address of the variable outside the lifetime area of the variable will be undefined behaviour.
On the other hand you can do the following, replace the int arr[n] with a static array but the size of the array must be declared.
...
static int arr[10];
...
This will fix the problem but you couldnt change the size of the array if the user inputs the wanted size of it.
A function dynamically creates an int array whose elements are predetermined to be int[2]. Is there any way to have a function assign values to that array and then return it to the caller.
The below code accomplishes this task but throws warning: initialization from incompatible pointer type [enabled by default]
#include <stdlib.h>
#include <stdio.h>
int *get_values()
{
int (*x)[2] = malloc(sizeof(int[2])*3);
x[0][0] = 1;
x[0][1] = 2;
x[1][0] = 11;
x[1][1] = 12;
x[2][0] = 21;
x[2][1] = 22;
return x;
}
int main()
{
int (*x)[2] = get_values();
int i;
for (i=0; i!=3; i++)
printf("x[%d] = { %d, %d }\n", i, x[i][0], x[i][1]);
}
I'm aware of the alternative where you dynamically allocate both dimensions, but this is something that I am curious about.
Rather than keep repeating the same clunky syntax it can be helpful to define a typedef in cases like this. This makes it easier to declare the correct return type for get_values:
#include <stdlib.h>
#include <stdio.h>
typedef int I2[2];
I2 * get_values(void)
{
I2 * x = malloc(sizeof(I2) * 3);
x[0][0] = 1;
x[0][1] = 2;
x[1][0] = 11;
x[1][1] = 12;
x[2][0] = 21;
x[2][1] = 22;
return x;
}
int main()
{
I2 * x = get_values();
int i;
for (i=0; i!=3; i++)
printf("x[%d] = { %d, %d }\n", i, x[i][0], x[i][1]);
free(x);
}
LIVE DEMO
Recommended reading: Don't repeat yourself (DRY).
And this is how it looks without a typedef:
int (*get_values(void))[2]
{
return NULL;
}
Pretty unreadable.
Notice in that function definition, if you replace get_values(void) with x you get: int (*x)[2], which is exactly what the pointer definition looks like.
I'm tasked with changing a C program to x86 asm, and this line is confusing me:
int x; arr[100]
Full program:
int max = 100;
int val = 0x7a;
int x, arr[100]; /*I have a feeling that it is in fact a typo, and my compiler was just being nice*/
main(){
x = 1;/*I just got an email saying this was an error*/
for (x = 1; x <= max; x++){
arr[x] = val;
}
}
I think it means an array, but I'm not sure.
It is an array of int. Before C99 in certain circumstances the type could be omitted in a declaration and then int was assumed. (Note that you are missing a ; after the declaration of your array in your example).
For example:
const x = 10; // valid in C89, not in C99
auto y = 10; // valid in C89, not in C99
In old-school C, variable and functions are typed as int by default. This explains both the type of arr and why main() has no return type specified.
This just looks like buggy code:
int max = 100;
int val = 0x7a;
// int x; arr[100] // Syntax error
int x, arr[100]; // Declare x as a scalar int, arr as an array of 100 ints
main() {
// x = 1; // Unnecessary, as the for loop initializes x
// for (x = 1; x <= max; x++) { // Writing to arr[100] is an error
for (x = 0; x < max; x++) { // Loop thru indices of arr[]
arr[x] = val; // Set arr[0..99] to 0x7a
}
}
coming from this question "What does (int (*)[])var1 stand for?" I tried to access the result of the cast like a multidimensional array. But I get following error: "assignment from incompatible pointer type" followed by a segmentation fault. I tried also some other variations, but none of them worked. How can I access the elements in var1 in the function example directly?
Thank you!
#include <stdlib.h>
int i(int n,int m,int var1[n][m]) {
var1[0][0]=5;
return var1[0][0];
}
int example() {
int *var1 = malloc(100);
// works
int var2;
var2 = i(10,10,(int (*)[])var1);
printf("var2=%i",var2);
//doesn't work I
int *var3;
var3=(int (*)[])var1; //"assignment from incompatible pointer type"
printf("var3[0][0]=%i",var3[0][0]);
//doesn't work II
int *var4;
var4=var1;
printf("var4[0][0]=%i",var4[0][0]); //" error: subscripted value is neither array nor pointer"
//doesn't work III
int **var5;
var5=var1;
printf("var5[0][0]=%i",var5[0][0]); // assignment from incompatible pointer type
return(1);
}
int main(){
int a;
a=example();
return(1);
}
int *var3;
var3 = (int (*)[])var1;
You are casting var1 which is already int* to int(*)[] (pointer to array of int) and assigning it to var3 which again is int*.
Just do
var3 = var1
Give this a shot. The following compiled with no warnings and ran under C99 (gcc -std=c99 -pedantic -Wall):
#include <stdio.h>
#include <stdlib.h>
int i(int n, int m, int (*var1)[m]) // C89 requires constant expression for
{ // array size
int j, k;
for (j = 0; j < n; j++)
for (k = 0; k < m; k++)
var1[j][k] = j*m+k;
return var1[0][0];
}
int example(void)
{
int *var1 = malloc(100 * sizeof *var1); // Thanks, Joseph!
int var2 = i(10, 10, (int (*)[10]) var1); // note the cast of var1 includes
// the array size
int (*var3)[10] = (int (*)[10]) var1; // note the type of var3
int j, k;
for (j = 0; j < 100; j++)
printf("var1[%2d] = %d\n", j, var1[j]);
for (j = 0; j < 10; j++)
for (k = 0; k < 10; k++)
printf("var3[%2d][%2d] = %d\n", j, k, var3[j][k]);
free(var1);
return var2;
}
int main(void)
{
int x = example();
printf("x = %d\n", x);
return 0;
}
First of all, note the types and the casts (most importantly, note how they match up). Note that I am specifying the size of the array dimension in the pointer-to-array casts. Also note that I declare var3 as a pointer to an array, not a simple pointer.
int example() {
int *var1 = malloc(100);
...
int *var3;
var3=var1;
printf("var3[0][0]=%i",var3[0][0]); //" error: subscripted value is neither array nor pointer"
return(1);
}
Here, var1 and var3 are both of type int*, which is roughly analogous to int[]. You've created a one-dimensional array and are trying to access them as a two-dimensional array. Change their type to int**, allocate the necessary memory, and that should fix your problem.
var3 needs to be a int** instead of an int*.
Edit
You're trying to use 2D array syntax where the actual data that you've created is actually a 1D array. You can use your i() function to give you the semantics you want but the data access needs to be converted to 1D indexing inside the function. Just make your function look like this:
int i(int n,int m,int* var1, int maxM) {
return var1[(maxM * n) + m];
}
Perhaps what you are looking for is:
int (*var1)[10][10] = malloc(sizeof *var1); // 400 bytes
i(10, 10, *var1);
printf("var1[0][0]=%i\n", (*var1)[0][0]);
Added: A complete code fragment for gcc might be:
#include <stdio.h>
#include <stdlib.h>
void i(int n, int m, int var1[][m]) { // n not needed
var1[0][0] = 5;
var1[1][2] = 6;
}
int main(void) {
int n = 10, m = 10;
int (*var1)[n][m] = malloc(sizeof *var1); // 400 bytes
i(n, m, *var1);
printf("var1[0][0]=%i\n",(*var1)[0][0]);
printf("var1[1][2]=%i\n",(*var1)[1][2]);
return 0;
}
For msvc, you'll need to make n and m constants, as in:
enum {n = 10, m = 10};
void i(int var1[][m]) {
var1[0][0] = 5;
var1[1][2] = 6;
}
int main(void) {
int (*var1)[n][m] = malloc(sizeof *var1);
i(*var1);
// ...
}