What exactly is the difference between blocks and loops? - c

Code-1: No warnings - No errors ... everything works fine
#include <stdio.h>
int main()
{
int r = 1;
printf("using %d\n", r);
for (int k = 1; k <= 2; k++)
{
int r = r * 2;
}
return 0;
}
Code-2: Wrong
#include <stdio.h>
int main()
{
int cnt = 1;
printf("using %d\n", cnt);
{
int cnt = cnt * 2;
}
return 0;
}
compiler response:
'cnt' is used uninitialized in this function [-Werror=uninitialized]
int cnt = cnt * 2;
So, I understand there is some difference between the loop and block in this case, but I am unable to figure out. Can anyone tell me how the scope of a variable works here?

They both have exactly the same problem i.e. r and cnt are self-initialized in respective programs.
This is potentially undefined because of use of uninitialized variables (which has indeterminate value) if they happen to have trap representation.
gcc happens to detect it one case and doesn't in the other case. gcc has -Wuninitialized -Winit-self options but it still doesn't detect the first case even with these options. Regardless, the issue remains (and the same) in both.

Related

signal: segmentation fault (core dumped) error

Wrote a program that multiply two arrays like this:
uv = u1v1 + u2v2 + u3v3 + ... un*vn
after getting from the user both of the arrays, i get a "signal: segmentation fault (core dumped)" error.
here's the code:
#include <stdio.h>
int scalar_product(int vectorU[], int vectorV[], int vectorLength) {
int i, sum = 0;
for (i = 0; i < vectorLength; i++)
sum += (vectorU[i] * vectorV[i]);
return sum;
}
void userInterface() {
int vectorLength = 0, i;
printf("Please enter the length of the vectors: ");
scanf("%d", &vectorLength);
int vectorU[vectorLength], vectorV[vectorLength];
printf("\nVector U:");
for (i = 0; i < vectorLength; i++) {
printf("\n%d) ", (i + 1));
scanf("%d", &vectorU[i]);
}
printf("\nVector V:");
for (i = 0; i < vectorLength; i++) {
printf("\n%d) ", (i + 1));
scanf("%d", &vectorV[i]);
}
printf(scalar_product(vectorU, vectorV, vectorLength));
}
main(void) {
userInterface();
}
This call of printf is incorrect
printf(scalar_product(vectorU, vectorV, vectorLength));
You need to write at least
printf( "%d\n", scalar_product(vectorU, vectorV, vectorLength));
Also it would be better to declare and define the function like
long long int scalar_product( const int vectorU[], const int vectorV[], int vectorLength) {
long long int sum = 0;
for ( int i = 0; i < vectorLength; i++)
sum += ( long long int )vectorU[i] * vectorV[i];
return sum;
}
To output the result you need to use the format string "%lld\n"..
The type long long int is used to avoid an overflow.
Another way is to declare the function return type as double.
Also you forgot to specify the return type int of the function main.
Here:
printf(scalar_product(vectorU, vectorV, vectorLength));
... you have failed to specify a format for printf. As a result, it attempts to interpret the result of scalar_product() as a pointer to the format string. Undefined behavior results.
If your compiler is not emitting a warning about that then you should either learn how to turn up the warning level so that it does, or else get a better compiler. If your compiler is emitting a warning about it, then take this as a lesson that it is not safe to ignore compiler warnings.
Probably you wanted somethign more like this:
printf("%d\n", scalar_product(vectorU, vectorV, vectorLength));
As a minor additional issue, you have forgotten the return type for main(). Your compiler is probably treating it as returning int, which turns out to be the right thing to do, but that doesn't make your code correct. You want:
int main(void) {
// ...
With those two changes, your program compiles for me without any diagnostics, and runs without error, producing the result I expect.
At least, for small vector lengths. If you try really large vectors then you might exceed the available space for allocating your vectors on the stack.

why are there two outputs for the same c prog below?

#include <stdio.h>
main()
{
int n;
n+=2;
printf("sum=%d", n);
return 0;
}
Here the 'Sum'=2
Another program:-
#include <stdio.h>
main()
{
int n,a=2;
n+=a;
printf("sum=%d", n);
return 0;
}
here the output 'sum' = 3
WHY so?? What is the problem in the code??
This is Undefined Behavior. Using uninitialized variables (n in both snippets) can produce unexpected results, meaning that running the first code twice might produce different outputs. There is no "correct" output for either of the codes, but if you'll set n to a specific value in both codes, you'll start getting consistent results.
This is UB (Undefined Behavior):
main()
{
int n;
printf("sum=%d", n);
return 0;
}
This is not:
main()
{
int n = 0;
printf("sum=%d", n);
return 0;
}
When you don't assign a value to a local variable in C, its value is undefined. So in some cases it will be 0, in some 1, in some, something else entirely. You cannot know what it will be and you should never rely on it. Instead, initialize your local variables:
int n = 0; // initialization
n += 2;
printf("sum=%d", n); // will always print 2

C - can variate location be promoted?

I am new to the language and was trying a simple code. I wanted to try to create a loop based on pointers. but it seems like you can not promote variate location like in assembler. or i just did it wrong? and if i really can't can i force a new variadate to be born in specific location? that was my code
#include <stdio.h>
int main(void) {
int firstnumber = 1;
int *beginning = &firstnumber;
printf("%i %i \n",firstnumber,beginning);
Test1(firstnumber,beginning);
return 0;
}
Test1 (int num, int begin)
{
int reserve = num;
if(num != 100)
{
&num +=2;
num = (reserve+1);
return Test1(num, begin);
}
else
{
int assist = begin;
while(*assist != 100)
{
printf("/n \n %i %i \n /n",num,assist);
&assist += 2;
}
}
}
I know it might look ridiculous but i'm really curious
You're thinking about this backwards. Pointers are the variables you can move around, so use them for anything you want to move around.
firstnumber is an integer variable - the compiler decides where it is stored and you can't tell the compiler to rebind the name firstnumber to a different location. You can, however, move a pointer around as much as you like. So,
void Test1(int num) {
&num +=2;
num = 42;
}
is nonsense, but
void Test2(int *num) {
num += 2;
*num = 42;
}
is fine - so long as num+2 is still a valid allocated object. For example, you could call it like
int i[5];
Test2(i); /* sets i[2] = 42 */
(if you pass in an array of fewer than 3 integers you get a runtime bug rather than a compile error, as Test2 damages your stack frame or other memory it shouldn't be touching).
No, you cannot promote/change variable location.
So this:
int num;
&num +=2;
does not make sense, and will result in an error:
error: lvalue required as left operand of assignment
&num +=2;
^~
Same for:
int assist;
&assist += 2;
Your code will compile only if you modify these statements (but now the logic is changed, you should work on that), but now it will result in an infinite loop, since your function never returns in the else case:
#include <stdio.h>
void Test1 (int num, int* begin);
int main(void) {
int firstnumber = 1;
int *beginning = &firstnumber;
printf("%i %i \n",firstnumber, *beginning);
Test1(firstnumber, beginning);
return 0;
}
void Test1 (int num, int* begin)
{
int reserve = num;
if(num != 100)
{
num +=2;
num = reserve + 1;
return Test1(num, begin);
}
else
{
int assist = *begin;
while(assist != 100)
{
printf("/n \n %i %i \n /n",num,assist);
assist += 2;
}
}
}
Good luck!
OK i checked the code deeper and got several conclusions:
function variable can not inherit his ancestor adress. therefore using a function for the task is useless unless i use some static variable
I had another conclusion but i don't remember what it was. sorry and thank you for your time

Command line number adding program produces wrong results

My Code:
#include <stdio.h>
int main(int argc, char*argv[]){
int n = argc;
int i, a, b, sum;
for(i = 0; i < n; i++){
sscanf(argv[i], "%u", &a);
b = a + sum;
sum = b;
}
printf("%d\n", sum);
return 0;
}
This piece of code should do ./a 0 1 2 3 must write terminal 6 But writes 42423.
The aim of the program was to issue the command-line arguments amount. But he does not make it correct angulation.
argv[0] holds the name of the executable which most likely you don't want to include in the loop. so, you need to start the loop from i=1.
As per your input, the argv[0] does not contain a numeric value hence causing a failure to sscanf(), leaving a uninitialized.
So, in your code, the primary issue is with,
b = a + sum;
where, for the first iteration, a and sum are both uninitialized local variables having indeterminate value. So, for the very first loop, you're invoking undefined behavior.
Also, a being an int, you need to use %d format specifier for it.
Two things to mention:
Always check for the return value of scanf() family for success.
Always initialize your local variables.
You are getting garbage value because you are not initialized varuiable sum on declaration.
Just initialize is as sum = 0 and u will get expected result.
Or u can use below code also.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char*argv[]){
int n = argc;
int i, a, b, sum=0;
for(i = 0; i < n; i++){
a = atoi(argv[i]);
sum += a;
}
printf("%d\n", sum);
return 0;
}

Segmentation Fault in C due to pointer

I have recently started coding in C, and am doing some stuff on project Euler. This is my code for challenge three so far. The only problem is when I run the compiled code it throws a segmentation fault. I think it may be due to a pointer I called, the suspect pointer is underneath my comment. I did some research into the subject but I cant seem to be able to fix the error. Any advice?
#include <stdio.h>
#include <stdbool.h>
#include <math.h>
bool is_prime(int k);
int * factors(int num);
int main(){
int input;
while (true){
printf("Enter a number to get the prime factorization of: ");
scanf("%d", &input);
if (is_prime(input) == true){
printf("That number is already prime!");
}else{
break;
}
}
//This is the pointer I think is causing the problem
int * var = factors(input);
int k;
for (k = 0; k < 12; k++){
printf("%d", var[k]);
}
}
bool is_prime(int k){
int i;
double half = ceil(k / 2);
for (i = 2; i <= half; i++){
if (((int)(k) % i) == 0){
return false;
break;
}
}
return true;
}
int * factors(int num){
int xi;
static int array[1000];
int increment = 0;
for (xi = 1;xi < ceil(num / 2); xi++){
if (num % xi == 0){
array[increment] = xi;
increment++;
}
}
}
The factors function has no return statement. It's supposed to return a pointer but it doesn't return anything.
Side note: Enable your compiler's warnings (e.g., with gcc -Wall -Wextra). If they're already enabled don't ignore them!
Your function is declared as
int * factors(int num);
but it's definition doesn't return anything and yet you are using it's return value in assignment. This triggers undefined behavior. It will compile if compiled without rigorous warnings and the return value will most likely be whatever random value happened to be left in the return register (e.g. EAX on x86).
C-99 Standard ยง 6.9.1/12 Function definitions
If the } that terminates a function is reached, and the value of the
function call is used by the caller, the behavior is undefined.

Resources