code 1:
.
.
int main()
{
char ch1[3];
ch1[0]=ch1[1] = NULL;
ch1[2]=0x01;
ch1[2] = ch1[2]<<2;
printf("%u", ch1[2]);
system("PAUSE");
return 0;
}
.
.
the output of code:1 is 4 (as expected).
code 2:
.
.
int main()
{
char ch1[3];
ch1[0]=ch1[1] = NULL;
ch1[2]=0x01;
*ch1 = *ch1<<2;
printf("%u", ch1[2]);
system("PAUSE");
return 0;
}
.
.
but the output of code:2 is 1 as not expected! in line 6 of code:2, the modification done was changing ch1[2] = ch1[2]<<2; to *ch1 = *ch1<<2;. I have tried treating the char array as one numerical value and have done the << operation; I believe that my method is incorrect. is there any correct method to treat an array as a single numerical value to do basic mathematical operations?
Update 1:
I have changed my code to the following:
int main()
{
char ch1[3];
ch1[0]=ch1[1] = NULL;
ch1[2]=0x01;
*(ch1+2) = *(ch1+2)<<9;
printf("%u", ch1[1]);
system("PAUSE");
return 0;
}
now I get the output:0. shouldn't I be getting the output 2 (i.e. 2^(9-8))? still, how to treat an array as a single numerical value?
right; but my actual question is if its possible to treat an array as a single value or not; that is by considering ch1[0], ch1[1], ch1[2] as a single block of memory of 24 bits.
The type of the pointer is important ch1 is similar to a pointer to char- char*. when you do *ch1 you are refering to the char that ch1 is pointing at. if you want to treat the entire array as a number you need to cast it into an integer, which is also problematic because your array has 3 bytes, and an integer has 4, so the top byte of x in the example below is pointing at, is actually undefined
int main()
{
char ch1[3];
ch1[0]=ch1[1] = 0;
ch1[2]=0x01;
int *x = (int*)ch1;
*x <<= 2;
printf("%u", ch1[2]);
system("PAUSE");
return 0;
}
Related
1)
How to access array element with array of pointers?
By pointer to an array we can access like this (∗a)[0]
,(∗a)[22]
,….. like this
right?
but how with array of pointer?
2)
Check these three codes , one of them use array and one of them use array of pointer, and 3rd one using double pointer, but all giving same output. Why??
#include <stdio.h>
int ptr[12];
int main(void) {
if(*(ptr+5)==*(ptr+3)){
printf("Equal");
}
else{
printf("Not Equal");
}
return 0;
}
#include <stdio.h>
int *ptr[12];
int main(void) {
if(*(ptr+5)==*(ptr+3)){
printf("Equal");
}
else{
printf("Not Equal");
}
return 0;
}
#include <stdio.h>
int **ptr[12];
int main(void) {
if(*(ptr+5)==*(ptr+3)){
printf("Equal");
}
else{
printf("Not Equal");
}
return 0;
}
In *(ptr+5):
ptr is the name of an array.
When an array is used in an expression and is not the operand of sizeof or unary & and is not a string literal used to initialize an array, it is converted to a pointer to its first element. So ptr points to element 0 of the array.
ptr+5 adds five, resulting in a pointer to element 5 of the array.
* dereferences the pointer, producing the contents of element 5 of the array.
Since the array is defined outside any function, it is initialized to zero. Therefore element 5 is zero, so *(ptr+5) is zero. Similarly, *(ptr+3) is zero, so comparing them shows they are equal.
The examples with int ptr[12];, int *ptr[12];, and int **ptr[12]; just change the types of the elements in the array. In each case *(ptr+5) and *(ptr+3) refer to elements 5 and 3 of the array. In each case, the values of the elements are zero (null pointers for the pointer types).
If you want to see differences between different elements of the array, then assign different values to the elements of the array.
Just keep incrementing the pointer as you go along reading the array. Analyze the
code below:
#include <stdio.h>
int main(void) {
int *ptr[3];
int a[] = { 0,1,2};
int b[] = { 3,4,5 };
int c[] = { 6,7,8 };
ptr[0] = a;
ptr[1] = b;
ptr[2] = c;
for (int i = 0;i < 3;i++)
printf("%d %d %d\n",*ptr[0]++,*ptr[1]++,*ptr[2]++);
return 0;
}
Answered in comments.
I was trying to understand pointers better, especially with string literals. I wanted to print a letter's bits in a string literal.
My main simply contains:
char *a = "A";
showBits(a);
and the function looks like that:
void showBits(char *character) {
int size = sizeof(char);
const unsigned int maxPow = 1<<(size*8-1); // 128
int j;
int temp = -1;
for(j=0;j<8;j++) {
temp = (*character)&maxPow;
printf("2%u", !!((*character)&maxPow));
*character = *character << 1;
}
}
Obviously the code does not work. I could make the code work with a[] = "A" but that was not my intention, I wanted to work with pointers to understand them better. I wonder, if there is a way to make this work?
I could imagine, that you can extract the bits, when you simply right shift maxPow and do a logial comparison with &, but is there a way to do it/work with the pointer?
Also I was thinking of passing the address to the function by showBits(&a), but can you then go through the addresses bit by bit?
The assignment to character tries to modify a string literal which is not possible. When you change the code to char a[] = "A", a stack-allocated array is created which is initalized with 'A''\0' and can be modified.
As a rule, you should always use a char const* when using string literals. This would have prevented the issue completely. I think the compiler should have generated a warning.
I think you could just pass the char by value and then everything will work.
void showBits(char character) {
const unsigned char maxPow = 128;
int j;
for(j=0;j<8;j++) {
printf("%u", 0 != (character & maxPow) );
character <<= 1;
}
}
int main()
{
char const* a = "\127";
showBits(*a);
}
I also simplified the function a bit because sizeof(char)is always 1 and removed some redundant code.
This is probably the most frequently asked question here (at least under C/C++).
Using "A", you have an array of characters "A\0" allocated in a read-only memory segment within your program (typically in the RO data-section).
Every time a function declaring char* a = "A" is called, a local variable is allocated on the stack and initialized to point to the address of "A\0" in memory.
Since this variable points to a read-only memory segment, any attempt to change the pointed data is likely to yield a memory access violation during runtime.
Every time a function declaring char a[] = "A" is called, a local array is allocated on the stack and initialized with the contents of "A\0" in memory.
Since this array resides in a writable memory segment, the program can safely change its contents during runtime (as long as it doesn't exceed its boundaries).
Instead of trying to do *character = *character << 1 and bitops with maxPow, just print (*character)&(1<<j).
int size_in_bits = sizeof(char)*8;
for(j=0;j<8;j++) {
printf("2%u", !!((*character)&(1<<(size_in_bits - 1 - j));
}
Try something like this:
void showBits(char *character) {
char result[10];
int mask = 0x80;
for (int j = 7; j >= 0; j -= 1) {
result[7-j] = (mask & *character) ? '1' : '0';
mask >>= 1;
}
result[8] = '\0';
printf("%s\n", result);
}
I would divide the functionality into two functions:
void showBitsOne(unsigned char c, int bits_left)
{
int bit = 0;
if ( bits_left <= 0 )
{
return;
}
// Print the bit.
bit = ((c & (1 << (bits_left-1))) == (1 << (bits_left-1)));
printf("%d", bit);
// Recurse.
showBitsOne(c, bits_left - 1);
}
void showBits(const char *character) {
while ( *character != '\0' )
{
showBitsOne(*character, CHAR_BIT);
printf(" "); // Just add a space between characters.
++character;
}
printf("\n");
}
With the following main function
int main()
{
showBits("abcd");
return 0;
}
I get the output:
01100001 01100010 01100011 01100100
int main()
{
unsigned char a[3];
unsigned char (*p)[3]=NULL;
unsigned char *q=NULL;
int i = 0;
a[0]=0;
a[1]=1;
a[2]=2;
p=&a;
for(i=0;i<3;i++){
if((*p)[3] == a[3]){
printf("*p[%d]:%d a[%d]:%d",i,(*p)[3],i,a[3]);
}
}
}
o/p:
*p[0]:0 a[0]:0*p[1]:0 a[1]:0*p[2]:0 a[2]:0
Exited: ExitFailure 14
I want to copy an array of size 3 to a pointer and to do a comparision. I have written a sample program. But i'm getting an error value.
I ran this using an online c compiler . (codepad.org)
Please help me in identifying my mistakes.
Your variable p is an array, not a pointer. You can't re-assign an array to point somewhere else, so the line
p = &a;
is not valid.
Also, C indexes from 0 as you seem to know, so comparisons using index [3] for arrays of size 3 are not valid.
Further, in your comparison loop you're not actually using i to index, but instead always comparing using the invalid constant index [3].
It's not very clear from your code (q is not used, for instance), but it sounds as if you want to do something like:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
unsigned char a[3];
unsigned char *p;
p = malloc(sizeof a);
if(p != NULL) /* If allocation succeeded, p is valid. */
{
int i;
memcpy(p, a, sizeof a);
for(i = 0; i < sizeof a; ++i)
{
if(p[i] == a[i])
printf("p[%d]:%d a[%d]:%d\n", i, p[i], i, a[i]);
}
free(p);
}
Of course, this will always print all the numbers, since memcpy() will never fail to copy the memory. :)
Here You have declared the return type of main function as int, but you are not returning anything from it.
So return any integer value (like 1) or make the main function's return type void.
I am writing a code to reverse a string in place:
void ReverseInPlace(char * x)
{
char * end = x;
int i;
i = 0;
char temp;
while(*end)
{
++end;//point tol end
++i;//count the lenght
}
--end;
printf("%s",end);
printf("%d",i);
while(i)
{
temp = *end;
printf("%s","\n");
printf("%c",temp);
end--;
x++;
i--;
}
printf("%s","\n");//blank line
printf("%s","\n");//blank line
printf("%s","-----");//blank line
printf("%s",x);//print original
}
Here are my confusions:
Even though I am able to print the characters in reverse, I want to reverse the string without using an array
I get error when I try to do the following:
*x = temp;
You say you are doing this:
ReverseInPlace("123456789");
You need to do something like this:
char str[] = "123456789";
ReverseInPlace(str);
Doing it the latter way allocates storage which you can modify, as opposed to modifying a literal string, which is illegal.
My proposal
#include <stdio.h> // printf
#include <string.h> // strlen
void swap(char* a , char* b)
{
char tmp;
tmp=*a;
(*a) = (*b);
(*b) = tmp;
}
void ReverseInPlace(char * x)
{
char * end = x;
int i,j,length;
char temp;
length = strlen(x);
//swap 1st with last, then 2nd with last-1, etc. Till we reach the middle of the string.
for(i=0,j=length-1 ; i<j ; ++i,--j)
swap( &x[i] , &x[j]);
}
main (){
char str[] = "123456789";
ReverseInPlace(str);
//ReverseInPlace("1234"); // this would lead to error, because "1234", can not be modified
printf("%s\n",str);
}
After middle is reached, you would swap elements which were already swapped by previous iterations. For illustration:
char* x = "1234";
1 2 3 4
4 2 3 1
4 3 2 1 // already reversed!
4 2 3 1
1 2 3 4 // if we continue till i==length-1 && j=0 , then we just get where we started
char *p="abcd123"; // ........string literal stored in read only memory mostly in text segment(where the code is stored) so you should never change value here as it may crash your program by writing onto code. Here p is pointing to address which maybe in text segment.
char q[]="abcd1234"; //..... the values can be changed and array size can be modified but address cant be changed because the array is nothing but a constant pointer. That's the problem with your code .....you are calling the function and parameter is a string literal whereas it should be a constant pointer. Further the storage class here is stack so u can modify the values.
I am writing the memset function and my code is below, I am having a problem
void* memsetFun(void* pointer, int c, int size) {
if ( pointer != NULL && size > 0 ) {
unsigned char* pChar = pointer;
int i = 0;
for ( i = 0; i < size; ++i) {
unsigned char temp = (unsigned char) c;
*pChar++ = temp; // or pChar[i] = temp (they both don't work)
}
}
return pointer;
}
I also tried pChar[i] = the value we want and still not working. It gives me some trash numbers that do not make any sense.
And I am calling it:
memsetFun(address, num, size);
printf("value at %p is %d\n", address, *((int*) address));
Where I call the address (I just input the address)
For example, if you to print the chars ( c ) it prints like a weird char that looks like ( for the value 4 )
0 0
0 4
Your code looks fine to me and several people here have commented that it works on their system.
So the obvious thing to do is to debug it - that's a skill that will come in handy quite a bit in future :-) You should learn it now.
What does the following code output when you run it?
void* memsetFun(void* pointer, int c, int size) {
printf("A %x %d %d\n", pointer, c, size);
if ( pointer != NULL && size > 0 ) {
printf("B\n");
unsigned char* pChar = pointer;
int i = 0;
for ( i = 0; i < size; ++i) {
printf("C %d (%d)", i, *pChar);
unsigned char temp = (unsigned char) c;
*pChar++ = temp; // or pChar[i] = temp (they both don't work)
printf(" -> (%d)", i, *(pChar-1));
}
}
printf("D\n");
return pointer;
}
From the output, it should be clear what paths the code is taking and what your parameters are (which will greatly assist the debugging process).
Update:
If you're filling your memory block with anything other than zeros and using this:
printf("value at %p is %d\n", address, *((int*) address));
to print it out, you will get strange results.
You're basically asking for a number of those bytes to be interpreted as an integer. So, for example, if you filled it with 0x02 bytes and you have a 4-byte integer type, you will get the integer 0x02020202 (33686018), not 0x02 as you may expect. If you want to see what the first character value is, use:
printf("value at %p is %d\n", address, *((char*) address));
And based on your latest question update:
For example, if you to print the chars ( c ) it prints like a weird char that looks like ( for the value 4 )
0 0
0 4
If that's a single character and you're printing it as a character, there's probably nothing wrong at all. Many output streams will give you that for a control character (CTRL-D in this case, ASCII code 4). If you instead filled it with ASCII code 0x30 (48), you would see the character '0' or ASCII 0x41 (65) would give you 'A'.
As pointed out already, your function works as it should. Here is a complete example:
#include <assert.h>
#include <string.h>
void* memsetFun(void* pointer, int c, int size) {
if ( pointer != NULL && size > 0 ) {
unsigned char* pChar = pointer;
int i = 0;
for ( i = 0; i < size; ++i) {
unsigned char temp = (unsigned char) c;
*pChar++ = temp; // or pChar[i] = temp (they both don't work)
}
}
return pointer;
}
int main() {
// Your memset
char a[10];
memsetFun(a, 'A', sizeof(a));
// Uses system memset for verification
char b[10];
memset(b, 'A', sizeof(b));
assert(sizeof(a) == sizeof(b));
assert(memcmp(a, b, sizeof(b)) == 0);
return 0;
}
return p; prevents this from compiling: p is not defined.
A minor efficiency issue—in practice it would have little effect, since any good compiler would rearrange it, but coding perfectionists wouldn't allow it to remain—the assignment to temp is inside the loop, but it is the same assignment every time. That is, the assignment to temp can be moved before the loop.
You return p, which isn't defined/doesn't point to anything in particular. Maybe you meant pointer?
The code is logically correct. With the p => pointer change it works correctly.
Clarify how exactly it is "not working". Perhaps you are not understanding what it is supposed to do?
You are probably getting trash numbers because you are casting from an int (4 bytes) to an unsigned char (1 byte), so if c > 255 or < 0 you won't be memsetting the values you are expecting to be.
I ran a test if your program setting the memory of an int vector of 5 elements setting with the value 0x01.
The problem here is that you are iterating in a vector of int for example (which is 4 bytes) but iterating over it using char pointer arithmetic (1 byte). If you want to memset 0x01 for example you will write this number per value in the vector: 00000001000000010000000100000001
which gives me the same value using the original memset.
Your function, as is, works for me.
I suppose you're calling it wrong. I call it like this
char a[100];
memsetFun(a, 0, sizeof a);
int b[100];
memsetFun(b, 0, sizeof b);
How are you calling your memsetFun()?
Edit
With
int b[100];
memsetFun(b, 9, sizeof b);
as an int is made up of 4 bytes (on my system) each value will be set to 0x09090909 or 151587081.
That is exactly what it's supposed to do. Your function is working perfectly fine. The value "0x4" is not the ASCII character '4'.