I am learning functions in C and having following problem with so many warnings :-(
code is as follows
#include <stdio.h>
void main(){
int a,c;
char *b; // declaring a pointer
char string[100]="something";
b = string; // assigning a pointer.. doing
printf("\n %s \n\n %s",string,*b); // doing this as a verification of the pointer, which is good - no seg faults
printf("Enter a and c:-");
scanf("%d %d",&a,&c);
find(a,c,*b);
printf("%s",*b);//segmentation fault core dumped:-'(
}
void find(int x, int y,char *b){
if(x>y)
*b = "a is greater than b";
else if(x=y)
*b = "both the values are equal";
else
*b = "b is greater than a";
}
warnings while compiling:--
function.c: In function ‘main’:
function.c:7:2: warning: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘int’ [-Wformat=]
printf("\n %s \n\n %s",string,*b); /*doing this jus to check is pointer working but no it is *not.segmentation error here "core dumped":-'(
^
function.c:12:2: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat=]
printf("%s",*b);//segmentation fault core dumped:-'(
^
function.c: At top level:
function.c:14:6: warning: conflicting types for ‘find’ [enabled by default]
void find(int x, int y,char *b){
^
function.c:11:2: note: previous implicit declaration of ‘find’ was here
find(a,c,*b);
^
function.c: In function ‘find’:
function.c:16:6: warning: assignment makes integer from pointer without a cast [enabled by default]
*b = "a is greater than b";
^
function.c:18:6: warning: assignment makes integer from pointer without a cast [enabled by default]
*b = "both the values are equal";
^
function.c:20:6: warning: assignment makes integer from pointer without a cast [enabled by default]
*b = "b is greater than a";
while running
segmentation error (core dumped)
Working cod:=---- with the help of community
#include <stdio.h>
#include <malloc.h>
void main(){
int a,c;
char *b =(char *)malloc(100);
char string[100]="something";
b = &string;
printf("\n %s \n\n %s",string,b);
printf("Enter a and c:-");
scanf("%d %d",&a,&c);
find(a,c,*b);
printf("\n%s",b);
}
void find(int x, int y,char *b){
if(x>y)
b = "a is greater than b";
else if(x=y)
b = "both the values are equal";
else
b = "b is greater than a";
}
output:-
something
something
enter a and c:-
10
20
something
**
means still it is not updating the value in the function...
**
I fix your code in less than a minute.No warnings and probably works (I don't speaking for logical problems).This means that your warnings were common mistake that even an experienced engineer might do.However a smart engineer will use warnings to fix these warnings.
#include <stdio.h>
#include <malloc.h>
void find(int, int,char*);
int main(){
int a,c;
char *b = NULL;
char string[100]="something";
b = &string[0];
printf("\n %s \n\n %s",string,b);
printf("Enter a and c:-");
scanf("%d %d",&a,&c);
find(a,c,b);
printf("\n%s",b);
return 0;
}
void find(int x, int y,char *b){
if(x>y)
b = "a is greater than b";
else if(x == y)
b = "both the values are equal";
else
b = "b is greater than a";
}
If you check this , you will see that there is no warning now.
Regarding on your effort to learn , I would try to explain warnings and try to estimate and give you a big picture of what those warnings would result.
warning: return type of ‘main’ is not ‘int’
-Here you take the answers in why we prefer to return int in main.
int main vs void main
warning: suggest parentheses around assignment used as truth value
-This is the worst error you have. = is for asign , == is for comparison
Difference between = and ==
The other too errors ,
conflicting type
and
implicit declaration
means that preprocessor of your compiler reached function invocation ( find(a,c,*b); ) before the declaration of the function.So one compiler might fix that and auto resolve this while another compiler might have an error.That's why preprocessor check firstly the header file , but since you don't have a header file (that's bad) , you should have a declaration of the function before you invoke this.
Whilst you fix that you would receive a warning ,
warning: passing argument 3 of ‘find’ makes pointer from integer
without a cast
This means that you are trying to pass the pointer of the pointer. b was a pointer at the first place , which hold the address of the first element of your char array.So y should have pass this without *.
THIS is a very good example on the question Why we don't ignore error
.Because an error about implicit declaration of a function , led as to discover another error , more significant than the first , that was hiding under the first warning.
Another note is that you don't need to malloc there.You malloc when you want to allocate an amount of memory on the heap and keep it alive before you free it.
PS:I hope I help and I hope you also take some benefit out of these.If you have any question , do not hesitate to comment(better in chat , to avoid spam in the community)
Thank you.
Related
I try to learn C with CS50 and try to write an exam score calculator. I have tried to write a dynamic code as below but I got error. This is my main code:
#include <cs50.h>
#include <stdio.h>
const int total_exam = 3 ; // Now we are creating a constant
//Prototype
//int get_scores(void);
int main(void)
{
// get exam scores
int *all_scores;
all_scores = get_scores();
printf("Your average score is %f\n", average(total_exam, all_scores) );
}
// create an function to get exam scores of the user
int *get_scores()
{
//get exam scores of the user
int scores[total_exam];
for (int i=0;i< total_exam; i++)
{
scores[i] = get_int("What's your exam score?: "); // each int uses 4 byte space
}
return scores;
}
// create an function to calculate average
float average(int length, int array[])
{
int sum=0;
for (int i=0 ; i<length; i++)
{
sum = sum+array[i];
}
return sum / (float) length ;
}
But when I try to execute it, I got error as below.
scores_with_array.c:14:18: error: implicit declaration of function 'get_scores' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
all_scores = get_scores();
^
scores_with_array.c:14:16: error: incompatible integer to pointer conversion assigning to 'int *' from 'int' [-Werror,-Wint-conversion]
all_scores = get_scores();
^ ~~~~~~~~~~~~
scores_with_array.c:16:42: error: implicit declaration of function 'average' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
printf("Your average score is %f\n", average(total_exam, all_scores) );
^
scores_with_array.c:16:42: error: format specifies type 'double' but the argument has type 'int' [-Werror,-Wformat]
printf("Your average score is %f\n", average(total_exam, all_scores) );
~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
%d
scores_with_array.c:22:6: error: conflicting types for 'get_scores'
int *get_scores()
^
scores_with_array.c:14:18: note: previous implicit declaration is here
all_scores = get_scores();
^
scores_with_array.c:33:12: error: address of stack memory associated with local variable 'scores' returned [-Werror,-Wreturn-stack-address]
return scores;
^~~~~~
scores_with_array.c:38:7: error: conflicting types for 'average'
float average(int length, int array[])
^
scores_with_array.c:16:42: note: previous implicit declaration is here
printf("Your average score is %f\n", average(total_exam, all_scores) );
^
7 errors generated.
I guess it's about array assigning but I could not understand it. Can you please help on this issue? Thanks in advance.
Why is your prototype for get_scores commented? It's causing the implicit declaration problem. And it's also wrong, it should be int *get_scores(void);.
The prototype for the average function is not present. C assumes it returns an int, which is causing more problems.
Why are you returning the scores array, after the function exits, the stack gets destroyed and memory leaks can happen. Allocate it like this: int *scores = malloc(sizeof(int) * total_exam).
Your code is kind of a mess, so I won't be surprised if further problems persist. Also, feel free to ask for clarifications by commenting.
a quick question. I'm trying to write a function which recieves a name of a string and prints its second character, But it won't compile (on http://ideone.com), can you address the issue? I don't see the problem as I am sending an address into the function, and asking to access the character in that address.
#include <stdio.h>
int main(void) {
char line[4] = "abc";
test(line);
return 0;
}
void test(int point) {
point++;
printf("%c",*point);
return;
}
The compile error that I am getting is -
Compilation error time: 0 memory: 10320 signal:0
prog.c: In function ‘main’:
prog.c:5:2: warning: implicit declaration of function ‘test’ [-Wimplicit-function-declaration]
test(line);
^~~~
prog.c: At top level:
prog.c:9:6: warning: conflicting types for ‘test’
void test(int point) {
^~~~
prog.c:5:2: note: previous implicit declaration of ‘test’ was here
test(line);
^~~~
prog.c: In function ‘test’:
prog.c:11:14: error: invalid type argument of unary ‘*’ (have ‘int’)
printf("%c",*point);
^~~~~~
Two problems here.
First, you use the function test before it's declared. So the function is implicitly declared as taking an unspecified number of arguments and returning int, i.e. int test(). This conflict with the definition void test(int point) that appears later.
The second issue is that you pass a char array (which decays to a char *) to test, but the function is expecting an int.
Move the definition of test to before main so that is defined before it's used, and change the point parameter from int to char *.
#include <stdio.h>
void test(char *point) {
point++;
printf("%c",*point);
return;
}
int main(void) {
char line[4] = "abc";
test(line);
return 0;
}
1) It wants a function prototype or for the function to be declared above your main.
2) The parameter point in
void test (int point)
is a pointer, not an int.
C is not comparing characters. I have tried many times and always with problems here.
My code is
#include <stdio.h>
#include <string.h>
int main(){
int palavra[16];
int frase[201];
gets(palavra);
gets(frase);
printf("%s\n",palavra);
printf("%s\n",frase);
int i;
int palavrasNaFrase=0;
int tamanhoPalavra=strlen(palavra);
int tamanhoFrase=strlen(frase);
printf("tamanho frase %d\n",tamanhoFrase);
for(i=0; i<tamanhoFrase; i++){
printf("i = %d\n",i);
printf("caracter: %c\n",palavra[0]);
printf("caracter: %c\n",frase[i]);
if(frase[i] == palavra[0]){
printf("C is not comparing characters\n");/*
int j=i+1,k=1;
int letrasIguais=1;
int cont=1;
while(cont<tamanhoPalavra){
if(frase[j]==palavra[k]){
letrasIguais++;
}
j++;
k++;
cont++;
}
if(letrasIguais==tamanhoPalavra){
palavrasNaFrase++;
}*/
}
}
//printf("%d\n",palavrasNaFrase);
return(0);
}
the input
ANA
ANAGOSTADEUMABANANA
the out
ANA
ANAGOSTADEUMABANANA
tamanho frase 19
i = 0
caracter: A
caracter: A
i = 1
caracter: A
caracter: O
i = 2
caracter: A
caracter: D
i = 3
caracter: A
caracter: A
i = 4
caracter: A
caracter: A
C is not comparing characters
i = 5
caracter: A
caracter: ©
i = 6
...
caracter:
0
Process returned 0 (0x0) execution time : 4.696 s
Press any key to continue.
Is so bugged, that i dont know what to do.
Please someone help me, if someone can find what is the problem, why is so bugged. There is soooo many bugs and things happening that should not be happening. I have tried and search so many times and always i have found the way to compare strings char by char using string[position]==string2[position] was right but in this program is not working and i have no idea why so many bugs! Please someone help me and give me a light! What am i doing wrong? Thanks
you're defining the arrays like this:
int palavra[16];
int frase[201];
while it reserves enough space, there's a problem when you're comparing char to char: you compare int to int (multi-char to multi-char) probably what you want here (and you probably had warnings about pointer types that you ignored):
if(frase[i] == palavra[0]){
You have to change your declarations to use char instead
char palavra[16];
char frase[201];
Compiling with warnings on you get this as expected. Fixing the warning would fix your code as well (extract of the warnings, redundant ones edited out):
$ gcc -Wall toto.c
toto.c: In function 'main':
toto.c:8:10: warning: passing argument 1 of 'gets' from incompatible pointer type
gets(palavra);
^
In file included from toto.c:1:0:
c:\gnatpro\7.4.2\x86_64-pc-mingw32\include\stdio.h:491:17: note: expected 'char *' but argument is of type 'int *'
^
In file included from toto.c:1:0:
c:\gnatpro\7.4.2\x86_64-pc-mingw32\include\stdio.h:491:17: note: expected 'char *' but argument is of type 'int *'
char *__cdecl gets(char *_Buffer) __MINGW_ATTRIB_DEPRECATED_SEC_WARN;
^
^
toto.c:11:5: warning: format '%s' expects argument of type 'char *', but argument 2 has type 'int *'
[-Wformat=]
printf("%s\n",frase);
^
toto.c:14:31: warning: passing argument 1 of 'strlen' from incompatible pointer type
int tamanhoPalavra=strlen(palavra);
^
I have found an example of multi thread programming which help to determine the prime numbers for a given integar n.it will also take number of thread as a input from the user.But the problem is when i try to execute it give me some errors which very hard to solve.Can anyone help?I am newbies at coding so any type of help and advice will be greatly appreciated.
#include <stdio.h>
#include <math.h>
#include <pthread.h> // required for threads usage
#define MAX_N 100000000
#define MAX_THREADS 25
int nthreads, n, prime[MAX_N+1], nextbase; // next sieve multiplier to be used
// lock for the shared variable nextbase
pthread_mutex_t nextbaselock = PTHREAD_MUTEX_INITIALIZER;
// ID structs for the threads
pthread_t id[MAX_THREADS];
// "crosses out" all odd multiples of k
void crossout(int k)
{ int i;
for (i = 3; i*k <= n; i += 2) {
prime[i*k] = 0;
}
}
// each thread runs this routine
void *worker(int tn) // tn is the thread number (0,1,...)
{ int lim,base,
work = 0; // amount of work done by this thread
// no need to check multipliers bigger than sqrt(n)
lim = sqrt(n);
do {
pthread_mutex_lock(&nextbaselock);
base = nextbase;
nextbase += 2;
// unlock the lock
pthread_mutex_unlock(&nextbaselock);
if (base <= lim) {
// don't bother crossing out if base known composite
if (prime[base]) {
crossout(base);
work++; // log work done by this thread
}
}
else return work;
} while (1);
}
main(int argc, char **argv)
{ int nprimes, // number of primes found
i,work;
n = atoi(argv[1]);
nthreads = atoi(argv[2]);
for (i = 3; i <= n; i++) {
if (i%2 == 0) prime[i] = 0;
else prime[i] = 1;
}
nextbase = 3;
// get threads started
for (i = 0; i < nthreads; i++) {
pthread_create(&id[i],NULL,worker,i);
}
for (i = 0; i < nthreads; i++) {
pthread_join(id[i],&work);
printf("%d values of base done\n",work);
}
nprimes = 1;
for (i = 3; i <= n; i++)
if (prime[i]) {
nprimes++;
}
printf("the number of primes found was %d\n",nprimes);
}
I have the following error while compiling:
In function ‘worker’:
Primes.c:67:12: warning: return makes pointer from integer without a cast [enabled by default]
else return work;
^
Primes.c: In function ‘main’:
Primes.c:88:7: warning: passing argument 3 of ‘pthread_create’ from incompatible pointer type [enabled by default]
pthread_create(&id[i],NULL,worker,i);
^
In file included from Primes.c:15:0:
/usr/include/pthread.h:244:12: note: expected ‘void * (*)(void *)’ but argument is of type ‘void * (*)(int)’
extern int pthread_create (pthread_t *__restrict __newthread,
^
Primes.c:88:7: warning: passing argument 4 of ‘pthread_create’ makes pointer from integer without a cast [enabled by default]
pthread_create(&id[i],NULL,worker,i);
^
In file included from Primes.c:15:0:
/usr/include/pthread.h:244:12: note: expected ‘void * __restrict__’ but argument is of type ‘int’
using: gcc -c -Wall -Wextra -Wconversion -std=gnu99 %f
where %f is the name of the file being compiled
The compiler output the following messages.
I added some commentary for each message that should point you to how to fix the problem.
compiler warning message:
:28:14: warning: conversion to 'int' from 'double' may alter its' value [-Wconversion]
lim = sqrt(n);
The function: sqrt() returns a 'double' but 'lim' is declared a 'int'
Suggest: cast the returned value to 'int'
lim = (int)sqrt(n);
compiler warning message:
:43:12: warning: return makes pointer from integer without a cast [enbled by default]
else return work;
the return type from the worker() function is void*
always exit the worker() function by:
pthread_exit( &work );
compiler warning message:
:24:18: warning: unused parameter 'tn' [-Wunused-parameter]
means the parameter 'tn' is not used. fix this by inserting in that function the line:
(void)tn;
compiler warning message:
47:1: warning: return type defaults to 'int' [enabled by default]
The signature of the main() function is not correct. without using the environment parameter, (almost never used), there are only 2 valid main() signatures and one optional signature.
use the correct signature for what your program needs.
int main( void )
int main( int argc, char *argv[] )
int main() // optional signature
compiler warning message:
50:4: warning: implicit declaration of function 'atoi' [-Wimplicit-function-declaration]
means the header file: stdlib.h has not been #include'd suggest inserting at top of file:
#include <stdlib.h>
compiler warning message:
61:7: warning: passing argument 3 of 'pthread_create' from incompatible pointer type [enabled by default]
means the third parameter to the function: pthread_create() was not a void pointer. suggest:
pthread_create(&id[i],NULL,worker,(void*)&i);
compiler warning message:
67:7: warning: passing argument 2 of 'pthread_join' from incompatible pointer type [enabled by default]
means the variable 'work' should be declared, in file global space, not in the thread function, as:
void * work;
there are other compiler warning messages output, but the above will eliminate them.
I.E. always start with the first compiler message, fix that, then re-compile. then fix the new first message.
Most of the problems with the syntax of the code could have been avoided by paying attention to the man pages for the system functions that were called in the posted code.
Note: the crossout() functions' logic is not correct. the code needs to start at k+k, continue until k<=n and step by k+=k I.E.
for( int k=i+i; k<(n+1); k+=k )
the code seems to be trying to implement a eratosthenes sieve for prime numbers google for the details.
unless your required to use threads, don't, they will just slow things down due to all the context swapping, etc.
this code logic:
for (i = 3; i <= n; i++)
{
if (i%2 == 0) prime[i] = 0;
else prime[i] = 1;
}
seems to be wrong, for one thing, the array prime[] will be initially all 0 because it is in the file global space. As far as I can tell, that code block is not needed at all.
because the work variable will be in the file global space, suggest an array of
void* work[ nthreads ];
then have the thread function: worker() actually use the passed parameter to select which of the entries in the array to be updating.
I am trying to call a c function with a const matrix argument using a const cast, but can't find the syntax that stops the gcc compiler complaining. The code below compiles without complaining if all "const " casts are removed. The quesion is similar to C function const multidimensional-array argument strange warning but no fully satisfactory solution was offered there. In the following code, if the first call to g() works, then the second call to g() should also work, since it is syntactically identical. But it does not. The second version of g() is preferred, because it does not require knowing in advance the type of the matrix.
/* file t.c */
void f(const int a[2]) {/*empty*/}
void g(const int b[2][2]) {/*empty*/}
int main()
{
int a[2];
int b[2][2];
f((const int (*)) a); /* ok */
f((const typeof(&a[0])) a); /* ok */
g((const int (*)[2]) b); /* ok */
g((const typeof(&b[0])) b); /* compiler complains */
}
$ gcc -o t t.c
t.c: In function ‘main’:
t.c:13:2: warning: passing argument 1 of ‘g’ from incompatible pointer type [enabled by default]
g((const typeof(&b[0])) b); /* compiler complains */
^
t.c:3:10: note: expected ‘const int (*)[2]’ but argument is of type ‘int (*)[2]’
void g(const int b[2][2]) {/*empty*/}
Yes, this lack of possibility to call a function with const 2D arrays with a non-const argument is really a defect in the C specification.
To move around it remember that
void g(const int b[2][2]) {/*empty*/}
is rewritten as
void g(const int (*b)[2]) {/*empty*/}
so this shows you how you'd have to convert, to a const int (*)[2], that is a pointer to an array of 2 double.
g( (const int (*)[2])b );
The const in the declaration header means that the function cannot change the contents of the argument. It is an information to the caller(compiler) and programmer. So there is no reason to make a const typecast then calling the function. It is totally superfluous.