Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is different between array String and common array in C?

#include<stdio.h>
int main()
{
    char str[7];
    scanf("%s",&str);

    for(i=0; i<7; i++)
    {
        printf("%x(%d) : %c\n",&str[i], &str[i], str[i]);
    }

    printf("\n\n%x(%d) : %c      or    %s",&str, &str, str, str);

    return 0;
}

I'm confused about pointer of C Array because of Array with String.

Actually I want to save each character for single line input.

It is worked but I found something strange...

The main issue is &str and &str[0] have same address value.

But str have String Value with %s..

str[0] have Char Value with %c..

I used str with %c then it has first two numbers of str's address.

What is going on in Array..?

Where is real address for Stirng value??

And how can scanf("%s",&str) distribute String to each char array space?

Input : 123456789
62fe40(6487616) : 1
62fe41(6487617) : 2
62fe42(6487618) : 3
62fe43(6487619) : 4
62fe44(6487620) : 5
62fe45(6487621) : 6
62fe46(6487622) : 7

62fe40(6487616) : @    123456789

This is result window of my code.

like image 672
JINU_K Avatar asked Oct 16 '22 06:10

JINU_K


2 Answers

You are confused because the string and the array are the same thing. - In the memory there are only data (and pointers to that data)

When you allocate an integer or a buffer for a string you reserve some of this memory. Strings in c is defined as a sequence of bytes terminated by one byte with the value 0 - The length is not known. With the fix length array you have a known size to work with.

The real value to the string is the pointer to the first character.

When you print with %c it expects a char - str[0] not the pointer - When you print with %s it expects a pointer to a sequence of chars.

printf("\n\n%x(%d) : %c      or    %s",&str, &str, str[0], str);
like image 70
Simson Avatar answered Nov 14 '22 22:11

Simson


What is different between array String and common array in C?

An array is a contiguous sequence of objects of one type.1

A string is a contiguous sequence of characters terminated by the first null character.2 So a string is simply an array of characters where we mark the end by putting a character with value zero. (Often, strings are temporarily held in larger arrays that have more elements after the null character.)

So every string is an array. A string is simply an array with two extra properties: Its elements are characters, and a zero marks the end.

&str and &str[0] have same address value.

&str is the address of the array. &str[0] is the address of the first element.

These are the same place in memory, because the first element starts in the same place the array does. So, when you print them or examine them, they will often appear the same. (Addresses can have different representations, the same way you might write “200” or “two hundred” or “2•102” for the same number. So the same address might sometimes look different. In most modern systems, an address is just a simple number for a place in memory, and you will not see differences. But it can happen.)

printf("%x(%d) : %c\n",&str[i], &str[i], str[i]);

This is not a correct way to print addresses. To print an address properly, convert it to void * and use %p3:

printf("%p(%p) : %c\n", (void *) &str[i], (void *) &str[i], str[i]);

printf("\n\n%x(%d) : %c or %s",&str, &str, str, str);

I used str with %c then it has first two numbers of str's address.

In the above printf, the third conversion specification is %c, and the corresponding argument is str. %c is intended to be used for a character,4 but you are passing it an argument that is a pointer. What may have happened here is that printf used the pointer you passed it as if it were an int. Then printf may have used a part of that int as if it were a character and printed that. So you saw part of the address shown as a character. However, it is a bit unclear when you write “it has the first two numbers of str's address”. You could show the exact output to clarify that.

Although printf may have used the pointer as if it were an int, the behavior for this is not defined by the C standard. Passing the wrong type for a printf conversion is improper, and other results can occur, including the program printing garbage or crashing.

And how can scanf("%s",&str) distribute String to each char array space?

The proper way to pass str to scanf for %s is to pass the address of the first character, &str[0]. C has a special rule for arrays like str: If an array is used in an expression other than as the operand of sizeof or the address-of operator &, it is converted to a pointer to its first element.5 So, you can use scanf("%s", str), and it will be the same as scanf("%s", &str[0]).

However, when you use scanf("%s",&str), you are passing the address of the array instead of the address of the first character. Although these are the same location, they are different types. Recall that two different types of pointers to the same address might have different representations. Because scanf does not have knowledge of the actual argument type you pass it, it must rely on the conversion specifier. %s tells scanf to expect a pointer to a character.6 Passing it a pointer to an array is improper.

C has this rule because some machines have different types of pointers, and some systems might pass different types of pointers in different ways. Nonetheless, often code that passes &str instead of str behaves as the author desired because the C implementation uses the same representation for both pointers. So scanf may actually receive the pointer value that it needs to make %s work.7

Footnotes

1 C 2018 6.2.5 20. (This means the information comes from the 2018 version of the C standard, ISO/IEC 9899, Information technology—Programming Languages—C, clause 6.2.5, paragraph 20.)

2 C 2018 7.1.1 1. Note that the terminating null character is considered to be a part of the string, although it is not counted by the strlen function.

3 C 2018 7.21.6.1 8.

4 Technically, the argument should have type int, and printf converts it to unsigned char and prints the character with that code. C 2018 7.21.6.1 8.

5 C 2018 6.3.2.1 3. A string literal used to initialize an array, as in char x[] = "Hello";, is also not converted to a pointer.

6 C 2018 7.21.6.2 12.

7 Even if a C implementation uses the same representations for different types of pointers, that does not guarantee that using one pointer type where another is required will work. When a compiler optimizes a program, it relies on the program’s author having obeyed the rules, and the optimizations may change the program in ways that would not break a program that followed the rules but that do break a program that breaks the rules.

like image 29
Eric Postpischil Avatar answered Nov 14 '22 21:11

Eric Postpischil