How do I fix integer to pointer conversion warning? - c

int main() {
int n, b, i, j;
char *thousand;
//char a;
char symbol [] = {'I', 'V', 'X', 'L', 'C', 'D', 'M'};
printf("Enter an integer between 0 and 10000: ");
scanf("%d",&n);
if( n >= 1000)
{
b = n / 1000;
for(i = 0; i < b; i++){
for (j = 0; j < i; j++)
{
thousand = symbol [6];
}
}
}
printf("%s",thousand);
return 0;
}
Here is the error that I am getting:
incompatible integer to pointer conversion assigning to 'char *' from 'char'; take the address with & [-Wint-conversion]

thousand is char *. symbol[6] is char. Thus the error message
incompatible integer to pointer conversion assigning to 'char *' from 'char'
You should change char *thousand to char thousand or thousand = symbol [6]; to thousand = symbol + 6 depending on what you want. Probably the first one.

The variable thousand is declared as:
char *thousand;
And in this line:
thousand = symbol [6];
thousand, which is a char * is assigned from symbol[6], which
is declared as:
char symbol []
Thus the error:
...conversion assigning to 'char *' from 'char'...
as symbol[6] is a char, not a char *.

Here you declared thousand as character pointer , which means it can store address of a character variable not a character itself. But you are trying to assign a character in thousand. Always remember that pointer stores address.

Related

warning: incompatible integer to pointer conversion initializing 'int *' with an expression of type 'int'; take the address with &

I have this code and I'm trying to debug it now and I get this error:
warning: incompatible integer to pointer conversion initializing
'int *' with an expression of type 'int'; take the address with &
[-Wint-conversion]
int * b = a[1];
The code I'm debugging is this:
#include<stdio.h>
int main() {
int ii;
int a[] = {1,2,3,4,5,6};
int * b = a[1];
for (ii=0;ii<6;ii++) {
printf("%d ",*(b+ii));
}
printf("\n");
return 0;
}
Given
int a[] = {1,2,3,4,5,6};
The array name variable a acts as a pointer i.e. the starting address for the consecutive memory block storing the values.
Thus, you can access the addresses in the loop either by incrementing the pointer i.e.
int *b=a;
for (int i = 0; i < 6; ++i) {
printf("%p\n",b++);
}
or through the pointer of the value at that index
for (int i = 0; i < 6; ++i) {
printf("%p\n", &a[i]);
}
int *b;
b is a pointer, a[1] is an integer...
Try:
int *b;
*b=a[1];
That will take us to the funny part. You have no memory for it!
Other way:
int *b=(a+1);
Yet another:
int *b=&a[1];

How to satisfy the warnings about incompatible types on printf()

I am going through the tutorials on learn-c.org. Coming up to the section about Arrays and Pointers, the first two lines of the example program issue a warning if I run them on my system:
char vowels[] = {'A', 'E', 'I', 'O', 'U'};
char *pvowels = &vowels;
The code runs, but I get the following warning:
warning: initialization of ‘char *’ from incompatible pointer type ‘char (*)[5]’ [-Wincompatible-pointer-types]
15 | char *pvowels = &vowels;
I can get rid of this warning if i cast it as
char *pvowels = (char *) &vowels;
But is that the correct way to approach that warning, just to cast it? It seems unnecessary in the first place, i don't really understand the difference between char * and char (*).
Next, the printf line issues a warning for the 3rd argument, saying:
warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 3 has type ‘char *’ [-Wformat=]
(same for arguments 5 and 7)
This one i don't even know how to cast in order to bypass the warning... What would be the correct way to print this one?
Entire program from their tutorial for reference:
char vowels[] = {'A', 'E', 'I', 'O', 'U'};
char *pvowels = &vowels;
int i;
// Print the addresses
for (i = 0; i < 5; i++) {
printf("&vowels[%d]: %u, pvowels + %d: %u, vowels + %d: %u\n", i, &vowels[i], i, pvowels + i, i, vowels + i);
}
// Print the values
for (i = 0; i < 5; i++) {
printf("vowels[%d]: %c, *(pvowels + %d): %c, *(vowels + %d): %c\n", i, vowels[i], i, *(pvowels + i), i, *(vowels + i));
}
With &vowels you get a pointer to the array itself, which is of type char (*)[5] as mentioned in the error message. What you seem to want is a pointer to the first element in the array which would be &vowels[0], or plain vowels as that decays to a pointer to its first element:
char *pvowels = vowels;
Also, when you want to print pointers with printf you need to use the %p format. And it prints "generic" pointers of type void *, so to be fully correct you need to cast all pointers to void *
printf("&vowels[%d]: %p, pvowels + %d: %p, vowels + %d: %p\n", i, (void *) &vowels[i], i, (void *) (pvowels + i), i, (void *) (vowels + i));
char vowels[] = {'A', 'E', 'I', 'O', 'U'};
char *pvowels = &vowels;
Here vowels is an array and if you take the address, you get the address of an array.
pvowels is of type pointer to char, not pointer to array.
If you want to get the address of the first character, just use the name of the array. It will decay to pointer to first element which is what you need:
char *pvowels = vowels;
Your second message comes because you use wrong types:
// Print the addresses
for (i = 0; i < 5; i++) {
printf("&vowels[%d]: %u, pvowels + %d: %u, vowels + %d: %u\n", i, &vowels[i], i, pvowels + i, i, vowels + i);
}
You want to print an address. The message is very clear that %u is used to print integers, not addresses. Use %p instead and provide parameter of type void*:
types:
// Print the addresses
for (i = 0; i < 5; i++) {
printf("&vowels[%d]: %p, pvowels + %d: %p, vowels + %d: %p\n", i, (void*)&vowels[i], i, (void*)(pvowels + i), i, (void*)(vowels + i));
}

Warning: assignment makes integer from pointer without a cast in shellsort algorithm

I'm writing a program to perform shellsort on an array of numbers. I first have to generate the sequence of numbers that shellsort will be performed with. This function is to generate numbers of the form 2^p*3^q that are less than the length of the array to be sorted. Then I sort the sequence array that I just generated. Here's my implementation of this:
long * Generate_2p3q_Seq(int length, int *seq_size) {
int ind = 0;
long * arr[1000];
int product;
int power = 1;
while (power < length) {
product = power;
while (product < length) {
arr[ind] = product;
product *= 3;
ind++;
}
power *= 2;
}
int i, j, k;
for (i = 0; i < ind; ++i) {
for (j = i + 1; j < ind; ++j)
{
if (arr[i] > arr[j])
{
k = arr[i];
arr[i] = arr[j];
arr[j] = k;
}
}
}
*seq_size = ind;
for (int count = 0; count < ind; count++) {
printf("arr[%d] = %li\n", count, arr[count]);
}
return arr;
}
The code is meant to return a long * array and set seq_size to the length of the sequence array. For example, if I'm given an array of 16 integers to be sorted, the sequence array generated here should be 8 integers (1, 2, 3, 4, 6, 9, 8, 12) and seq_size should equal 8. I believe my understanding of pointers is wrong because my terminal output looks like this:
sequence.c: In function ‘Generate_2p3q_Seq’:
sequence.c:14:16: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
arr[ind] = product;
^
sequence.c:26:11: warning: assignment makes integer from pointer without a cast [-Wint-conversion]
k = arr[i];
^
sequence.c:28:16: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
arr[j] = k;
^
sequence.c:34:25: warning: format ‘%li’ expects argument of type ‘long int’, but argument 3 has type ‘long int *’ [-Wformat=]
printf("arr[%d] = %li\n", count, arr[count]);
~~^ ~~~~~~~~~~
%ln
sequence.c:36:10: warning: return from incompatible pointer type [-Wincompatible-pointer-types]
return arr;
^~~
sequence.c:36:10: warning: function returns address of local variable [-Wreturn-local-addr]
However, I'm not sure how to change this to make it work. I call this function with:
long * sequence = Generate_2p3q_Seq(size, &seq_size);
Please let me know if there's any information I've left out, I really appreciate any help.
There are two main issues here. First, you declare arr as long *arr[1000], which means it is an array of pointer to long, not an array of long. That is why you're getting about conversions between pointers and integers.
The proper way to define an array of long is:
long arr[1000];
But this then leads to the second problem, namely that you are returning a pointer to a local variable. When the function returns its local variables go out of scope, so the returned pointer no longer points to valid memory.
To fix this, declare arr as a pointer and use malloc to dynamically allocate memory for it:
long *arr = malloc((product * power) * sizeof *arr);
if (!arr) {
perror("malloc failed");
exit(1);
}
Then you can return the value of arr, which points to dynamically allocated memory.
Pass a pointer to an array as an additional parameter, and manipulate that.
void Generate_2p3q_Seq(long * arr, int length, int *seq_size) {
// Method stores result in pre-initialized arr.
}
// Call with:
long arr[1000];
Generate_2p3q_Seq(arr, length, seq_size)
// Result stored correctly in arr.

Add two int chars together into one char array or string

How can i add Add two int chars together into one char array or string like :
char *s;
int a = 'A';
int b = 'B';
s = a + b;
the terminal givs me :
incompatible integer to pointer conversion assigning to 'char *' from
'int'
Have a look at sprintf to print the values to a string.
char my_cstring[32] = "";
char a = 'A';
char b = 'B';
sprintf(my_cstring, "%c%c", a, b);
// output: "AB"

Devious pointer expression (int*)arr

I'm learning c and I'm finding difficulties with the expression (int*)arr in the line 18. The whole program is
int main () {
char c, arr['z'-'a'], *pChar;
int i, *pInt, int matr = 74 ;
for ( c='a'; c<'z'; c++) {
arr[c-'a'] = c;
printf("%c ", arr[c-'a']);
}
printf("\n");
pChar = arr + matr%15;
for (i=0; i< 5; i++) {
printf("%c ", *pChar);
pChar++;
}
printf("\n");
pInt = (int *)arr + matr%2;
for (i=0; i<5; i++) {
pChar = (char *)pInt;
printf("%c ", *pChar);
pInt++;
}
return 0;
}
Thank you
You declared arr as char type. As the name of an array can be used as a pointer to its first element ; arr is a pointer to first char of array arr and is of type char *.
pInt is of type int *, for the expression
pInt = (int *)arr + matr%2;
a cast is needed to covert arr to int * type in your program.
In C when the name of an array is used as a value it represents the address of the first element (&arr[0]).
In first case (line 11) you have pChar = &arr[matr%15] because pChar is a char*
In second case (line 18) you have pInt = (int *) &arr[matr%15]. You have to cast pointer to char into pointer to int, bacause pInt is a int*
The other answers have been telling you that you need to use a cast to convert arr to int*.
Better: Don't convert arr to int*.
char c, arr['z'-'a'], *pChar;
int i, *pInt, int matr = 74 ;
This would be clearer if you'd declare each variable on a line of its own:
char c;
char arr['z'-'a'];
char *pChar;
int i;
int *pInt;
int matr = 74;
You've declared arr as an array of char. Assuming an ASCII character set, it has 26 characters. You probably wanted it to have 26.
An expression of array type is implicitly converted, in most contexts, to a pointer to its first element. So arr usually becomes an expression of type char*, equivalent to &arr[0].
Converting that char* pointer to int* (which does require a cast) gives you a pointer to an int that overlays the first sizeof (int) elements of the array.
That's a very odd thing to do, and it actually has undefined behavior (arr doesn't necessarily have the proper alignment to store int objects).
If you want to store int objects, declare an array of int.
I haven't studied your code enough to understand what it's intended to do, but there's almost certainly a better way to do it.

Resources