Initialize a double array with int values in C - c

I'm learning some c now, and must do an exercise for the university. I need an double array which should be filld with int values. So I've this.
#include <stdio.h>
#include <stdlib.h>
int main( int argc, char *argv[] ) {
int size=0, i=0;
printf("Enter size of array: ");
scanf("%d", &size);
double* field = malloc(size * sizeof(double));
double value;
for(i=0; i<size; i++) {
field[i] = i;;
}
for(i=0; i<size; i++) {
printf("Field%i: %d\n",i, field[i]);
}
free(field);
return 0;
}
But, when I execute it all values are set to 0.
Enter size of array: 10
Field0: 0
Field1: 0
Field2: 0
Field3: 0
Field4: 0
Field5: 0
Field6: 0
Field7: 0
Field8: 0
Field9: 0

printf's %d stands for decimal integer, not double.
So this line:
printf("Field%i: %d\n",i, field[i]);
should be:
printf("Field%i: %f\n",i, field[i]);
Using the wrong format specifier is undefined behavior which you had earlier.
From standard
If any argument is not the correct type for the corresponding
conversion specification, the behavior is undefined.
Also check the return value of malloc. It let's you know whether the allocation failed (returns NULL) or not.
A bit more insight from David C. Rankin's comment
The %d format
specifier was looking for 4-bytes (sizeof int bytes) in memory
ordered based on the endianess of your machine. When you provided an
8-byte (sizeof double) value comprised of a sign-bit, normalized
exponent and mantissa, it had no idea what to do with it.
Well here in printf we can use %f instead of %lf also which has added benefit of compatibility with pre-C99 versions and also it is shorter. (chux pointed this).

I don't think whether malloc function allocated the memory for the array. Check the syntax of malloc and also the return type.

Related

Using strlen() with Array Integers or Float [duplicate]

This question already has answers here:
How do I determine the size of my array in C?
(24 answers)
Closed 3 years ago.
Is there a way, I can use of strlen() to find the length of the arrays, instead of specifying in the loop.
First Code: Working With x < 4 Which is the size of the array of temps[4].
#include <stdio.h>
#include <string.h>
int main(){
float temps[4] = {72.5, 73.4, 74.7, 75.2};
int x;
printf("Local Temperatures\n");
for(x = 1; x < 4; x++){
printf("Station %d: %.1f\n",x,temps[x]);
}
}
My Second Code, Not Working, But Looking At What, I Am Trying To achieve with strlen() to find the size of the array.:
#include <stdio.h>
#include <string.h>
int main(){
float temps[4] = {72.5, 73.4, 74.7, 75.2};
int x;
float size;
size = temps;
printf("Local Temperatures\n");
for(x = 1; x < strlen(size); x++){
printf("Station %d: %.1f\n",x,size[x]);
}
}
strlen is effectively an optimized version of the following:
size_t len = 0;
const char *p = s;
while (!*p) {
++len;
++p;
}
You can easily adapt that.
size_t len = 0;
const float *p = s;
while (*p != 0.0) {
++len;
++p;
}
Of course, that means you need a sentinel value just like you had for the string.
float temps[] = { 72.5, 73.4, 74.7, 75.2, 0.0 };
While you can use a value other than 0.0 as your sentinel value, using a sentinel value might not be desirable, so you might not really want to take the same approach as one does for strings.
For an array (as opposed to a pointer), you can use the following to determine the number of elements in the array:
sizeof(a)/sizeof(*a)
That means you can use the following to determine the number of elements in temps:
sizeof(temps)/sizeof(*temps)
Simple method is to get the size of a array is by sizeof(temps)/sizeof(temps[0])
something like,
for(x = 0; x < sizeof(temps)/sizeof(temps[0]); x++){
printf("Station %d: %.1f\n",x,temps[x]);
}
Note: In your snippet array access is done from 1 to (size) instead 0 to (size-1) which is out of bound access.
Short answer: no.
strlen expects an argument of type char *, which points to the first character of a string, which is a sequence of character values including a zero-valued terminator. strlen returns the number of characters before the terminator:
/**
* A naive implementation of strlen. Actual implementations
* are a little more clever.
*/
size_t strlen( const char *str )
{
size_t count = 0;
while( str[count] )
count++;
return count;
}
The important thing to remember is that strlen returns the length of the string, not the size of the array containing the string. If you have something like
char foo[1024] = “bar”;
the strlen( foo ); returns 3.
If you tried to pass an integer or floating point array to strlen the compiler would yell at you because of the wrong argument type. You could work around this by casting the argument to char *, but you would still likely get a wrong answer, not only because integer and float types are multiple chars wide, but also because such a value may have an embedded zero-valued byte. For example, the integer value 16 is represented as the bytes 0x00, 0x00, 0x00, 0x10. If that’s the first element of your integer array, then strlen would return 0 on a big-endian platform and 1 on a little-endian platform.
If you defined the array, then you know how big it is. If you’re writing a function that receives an array argument, then you must either also receive the size as a separate argument, or you must rely on the presence of a sentinel value in the array.
Just do this to get the length of your float array,
int main()
{
float ar[4] = {1.1,1.2,1.3,1.4};
float b;
printf("Array Size : %d\n",sizeof(ar)/sizeof(b));
return 0;
}
You'll get the total number of element of your array , which you can use further in a loop to print the elements of array.
Note: Do not Use sizeof in case of pointers.
strlen() takes a "const char *" type value as argument. So it cannot be used with integer or float arrays.

Unable to print the array values in C

It's just a simple C program to display the array elements taken from the user but idk why am getting the garbage values when trying to print the array... if anyone could help i would really appreciate that... thanks!!
#include <stdio.h>
#include <stdlib.h>
double *array_dou;
double* initializeDoubles(int *maxdouble)
{
printf("Enter the max. double value the program should support: ");
scanf("%d",maxdouble);
array_dou = (double *) malloc((*maxdouble)*sizeof(double));
if(array_dou == NULL)
{
printf("Error! memory not allocated.");
exit(-1);
}
return array_dou;
}
int enterDouble(double *doubles,int dcount,int maxdouble)
{
for(dcount=0; dcount<maxdouble; dcount++)
{
printf("Please enter a double value: ");
scanf("%f",&doubles[dcount]);
}
return dcount;
}
int main()
{
int maxdouble;
int dcount=0;
double *doubles;
doubles = initializeDoubles(&maxdouble);
dcount = enterDouble(doubles,dcount,maxdouble);
printf("\nDouble array\n");
for(int j=0;j<dcount;j++)
{
printf("%lf ",doubles[j]);
}
return 0;
}
Because you are calling enterDouble only once and it reads only one value. Besides you are accessing the memory out of bounds. You allocated dcount number of elements, so you can access the memory only through the indices 0 to dcount - 1, yet you are passing dcount to enterDouble, thus you are trying to write at index dcount (one past the limit).
All other entries are uninitialized, so there you have two reasons why you see "garbage": the undefined behaviour of accessing memory out of bounds and the fact that you haven't initialized any of the doubles.
What you need to do is call enterDouble for all indices:
for(int j = 0; j < dcount; ++i)
enterDouble(doubles, j);
And the dcount++; in enterDouble makes to me no sense, the caller knows which index it it passing, no need to returns the same index + 1.
Also see do not cast malloc and you are not freeing the memory you've
allocated.
Also the proper conversion specifier for reading doubles with scanf is %lf, not %f.
man scanf
...
l Indicates either that the conversion will be one of d, i, o, u, x, X, or n and the next pointer is a pointer to a long int or
unsigned long in (rather than int), or that the conversion will be one of e, f, or g and the next pointer is a pointer to
double (rather than float).
...
f Matches an optionally signed floating-point number; the next pointer must be a pointer to float.

Why only these numbers printed

Below is my code
main()
{
int c[ ]={2.8,3.4,4,6.7,5};
int j,*p=c;
for(j=0;j<5;j++){
printf(" %d ",*p);
++p; }
}
The output was
2 3 4 6 5
How the above code is executed?
it's executed exactly they way you think it's executed: you print the array elements in your for loop, however, you made the array elements as int, therefore, when printing 2.8 which is double, the compiler ignores whatever after the point, means, it sees it as 2 rather than 2.8
When you write the statement :
int c[ ]={2.8,3.4,4,6.7,5};
the decimal values are automatically converted to integers.So the array stores
2,3,4,6,5
So your output becomes as it is.
To work with decimals use float type variables.
float c[ ]={2.8,3.4,4,6.7,5};
The int c[] is integer.You can try it.
float c[] = { 2.8, 3.4, 4, 6.7, 5 };
float *p = c;
for (int j = 0; j<5; j++){
printf(" %f ", *p);
p = p+1;
}
if you use 'float j' instead of 'int j' and '%f' instead of '%d' you would get what you want.
Here due to the using of int j and %d, only the part before the decimal point of each number in the array is printed.

The result of a modulo operation is negative

Why does the following C code produce negative numbers as output? And how do I prevent this from happening?
#include <stdio.h>
int main()
{
int i;
char buf[1024];
for (i = 0; i < 1024; i++)
buf[i] = i%256;
for (i=0; i<1024; i++) {
printf("%d ", buf[i]);
if (i%32==31)
printf("\n");
}
}
Let's look at this line of code:
buf[i] = i%256;
Here, i % 256 is computed as a value of type int. However, buf is an array of chars, so when the value is assigned into the array, it's truncated to a char. If the result of the modulus is outside of the range of positive values that can be stored in a char, it may end up wrapping around and being stored as a negative number instead.
In other words, it's not that the modulus produced a negative value as much as you stored the result in a type that can't hold it. Try changing the array to an int array or unsigned char array and see if that fixes things.
Hope this helps!

Using memset for integer array in C

char str[] = "beautiful earth";
memset(str, '*', 6);
printf("%s", str);
Output:
******ful earth
Like the above use of memset, can we initialize only a few integer array index values to 1 as given below?
int arr[15];
memset(arr, 1, 6);
No, you cannot use memset() like this. The manpage says (emphasis mine):
The memset() function fills the first n bytes of the memory area pointed to by s with the constant byte c.
Since an int is usually 4 bytes, this won't cut it.
If you (incorrectly!!) try to do this:
int arr[15];
memset(arr, 1, 6*sizeof(int)); //wrong!
then the first 6 ints in the array will actually be set to 0x01010101 = 16843009.
The only time it's ever really acceptable to write over a "blob" of data with non-byte datatype(s), is memset(thing, 0, sizeof(thing)); to "zero-out" the whole struture/array. This works because NULL, 0x00000000, 0.0, are all completely zeros.
The solution is to use a for loop and set it yourself:
int arr[15];
int i;
for (i=0; i<6; ++i) // Set the first 6 elements in the array
arr[i] = 1; // to the value 1.
Short answer, NO.
Long answer, memset sets bytes and works for characters because they are single bytes, but integers are not.
On Linux, OSX and other UNIX like operating systems where wchar_t is 32 bits and you can use wmemset() instead of memset().
#include<wchar.h>
...
int arr[15];
wmemset( arr, 1, 6 );
Note that wchar_t on MS-Windows is 16 bits so this trick may not work.
The third argument of memset is byte size. So you should set total byte size of arr[15]
memset(arr, 1, sizeof(arr));
However probably, you should want to set value 1 to whole elements in arr. Then you've better to set in the loop.
for (i = 0; i < sizeof(arr)/sizeof(arr[0]); i++) {
arr[i] = 1;
}
Because memset() set 1 in each bytes. So it's not your expected.
Since nobody mentioned it...
Although you cannot initialize the integers with value 1 using memset, you can initialize them with value -1 and simply change your logic to work with negative values instead.
For example, to initialize the first 6 numbers of your array with -1, you would do
memset(arr,-1,6*(sizeof int));
Furthermore, if you only need to do this initialization once, you can actually declare the array to start with values 1 from compile time.
int arr[15] = {1,1,1,1,1,1};
Actually it is possible with memset_pattern4 which sets 4 bytes at a time.
memset_pattern4(your_array, your_number, sizeof(your_array));
No, you can't [portably] use memset for that purpose, unless the desired target value is 0. memset treats the target memory region as an array of bytes, not an array of ints.
A fairly popular hack for filling a memory region with a repetitive pattern is actually based on memcpy. It critically relies on the expectation that memcpy copies data in forward direction
int arr[15];
arr[0] = 1;
memcpy(&arr[1], &arr[0], sizeof arr - sizeof *arr);
This is, of course, a pretty ugly hack, since the behavior of standard memcpy is undefined when the source and destination memory regions overlap. You can write your own version of memcpy though, making sure it copies data in forward direction, and use in the above fashion. But it is not really worth it. Just use a simple cycle to set the elements of your array to the desired value.
Memset sets values for data types having 1 byte but integers have 4 bytes or more , so it won't work and you'll get garbage values.
It's mostly used when you are working with char and string types.
Ideally you can not use memset to set your arrary to all 1.Because memset works on byte and set every byte to 1.
memset(hash, 1, cnt);
So once read, the value it will show 16843009 = 0x01010101 = 1000000010000000100000001
Not 0x00000001
But if your requiremnt is only for bool or binary value then we can set using C99 standard for C library
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h> //Use C99 standard for C language which supports bool variables
int main()
{
int i, cnt = 5;
bool *hash = NULL;
hash = malloc(cnt);
memset(hash, 1, cnt);
printf("Hello, World!\n");
for(i=0; i<cnt; i++)
printf("%d ", hash[i]);
return 0;
}
Output:
Hello, World!
1 1 1 1 1
The following program shows that we can initialize the array using memset() with -1 and 0 only
#include<stdio.h>
#include<string.h>
void printArray(int arr[], int len)
{
int i=0;
for(i=0; i<len; i++)
{
printf("%d ", arr[i]);
}
puts("");
}
int main()
{
int arrLen = 15;
int totalNoOfElementsToBeInitialized = 6;
int arr[arrLen];
printArray(arr, arrLen);
memset(arr, -1, totalNoOfElementsToBeInitialized*sizeof(arr[0]));
printArray(arr, arrLen);
memset(arr, 0, totalNoOfElementsToBeInitialized*sizeof(arr[0]));
printArray(arr, arrLen);
memset(arr, 1, totalNoOfElementsToBeInitialized*sizeof(arr[0]));
printArray(arr, arrLen);
memset(arr, 2, totalNoOfElementsToBeInitialized*sizeof(arr[0]));
printArray(arr, arrLen);
memset(arr, -2, totalNoOfElementsToBeInitialized*sizeof(arr[0]));
printArray(arr, arrLen);
return 0;
}

Resources