简体   繁体   English

C中的数组字符串和公共数组有什么不同?

[英]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. 由于Array with String,我对C数组的指针感到困惑。

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. 主要问题是&str&str [0]具有相同的地址值。

But str have String Value with %s.. str的字符串值为%s ..

str[0] have Char Value with %c.. str [0]的 Char 值为 %c ..

I used str with %c then it has first two numbers of str 's address. 我使用str和%c然后它有前两个str的地址。

What is going on in Array..? Array中发生了什么?

Where is real address for Stirng value?? Stirng值的真实地址在哪里?

And how can scanf("%s",&str) distribute String to each char array space? scanf(“%s”,&str)如何将String分配给每个char数组空间?

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. 这是我的代码的结果窗口。

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. c中的字符串定义为由一个字节终止的字节序列,其值为0 - 长度未知。 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. 当你用%c打印时,它需要一个char-str [0]而不是指针 - 当你用%s打印时,它需要一个指向一系列字符的指针。

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

What is different between array String and common array in C? C中的数组字符串和公共数组有什么不同?

An array is a contiguous sequence of objects of one type. 数组是一种类型的连续对象序列。 1 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. 2所以字符串只是一个字符数组,我们通过放置一个值为零的字符来标记结尾。 (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&str [0]具有相同的地址值。

&str is the address of the array. &str是数组的地址。 &str[0] is the address of the first element. &str[0]是第一个元素的地址。

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•10 2 ” 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.) (地址可以有不同的表示形式,对于相同的数字可以写“200”或“2”或“2•10 2 ”。因此相同的地址有时可能看起来不同。在大多数现代系统中,地址是只是内存中一个地方的简单数字,你不会看到差异。但它可能会发生。)

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 %p 3 : 要正确打印地址,请将其转换为void *并使用%p 3

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. 我使用str和%c然后它有前两个str的地址。

In the above printf , the third conversion specification is %c , and the corresponding argument is str . 在上面的printf ,第三个转换规范是%c ,相应的参数是str %c is intended to be used for a character, 4 but you are passing it an argument that is a pointer. %c旨在用于字符, 4但是您传递的是一个指针参数。 What may have happened here is that printf used the pointer you passed it as if it were an int . 这里可能发生的是printf使用你传递它的指针,就好像它是一个int Then printf may have used a part of that int as if it were a character and printed that. 然后printf可能已使用该int的一部分,就像它是一个字符并打印出来一样。 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”. 但是,当你写“它有str的前两个数字地址”时,有点不清楚。 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. 虽然printf可能使用了指针,就好像它是一个int ,但是C标准没有定义它的行为。 Passing the wrong type for a printf conversion is improper, and other results can occur, including the program printing garbage or crashing. printf转换传递错误的类型是不合适的,并且可能发生其他结果,包括程序打印垃圾或崩溃。

And how can scanf("%s",&str) distribute String to each char array space? scanf(“%s”,&str)如何将String分配给每个char数组空间?

The proper way to pass str to scanf for %s is to pass the address of the first character, &str[0] . str传递给scanf for %s的正确方法是传递第一个字符&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. C具有像阵列的特别规则str :如果阵列在比作为操作数以外的表达式中使用sizeof或地址运算符& ,它被转换成一个指针到它的第一个元素。 5 So, you can use scanf("%s", str) , and it will be the same as scanf("%s", &str[0]) . 5因此,您可以使用scanf("%s", str) ,它将与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. 但是,当您使用scanf("%s",&str) ,您传递的是数组的地址而不是第一个字符的地址。 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. 因为scanf不知道您传递的实际参数类型,所以它必须依赖于转换说明符。 %s tells scanf to expect a pointer to a character. %s告诉scanf期望指向一个字符的指针。 6 Passing it a pointer to an array is improper. 6传递一个指向数组的指针是不合适的。

C has this rule because some machines have different types of pointers, and some systems might pass different types of pointers in different ways. C有这个规则,因为有些机器有不同类型的指针,有些系统可能以不同的方式传递不同类型的指针。 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. 尽管如此,通常代码传递&str而不是str行为与作者所期望的一样,因为C实现对两个指针使用相同的表示。 So scanf may actually receive the pointer value that it needs to make %s work. 所以scanf实际上可能会收到%s工作所需的指针值。 7 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.) 1 C 2018 6.2.5 20.(这意味着信息来自2018版C标准,ISO / IEC 9899, 信息技术 - 编程语言-C ,第6.2.5条,第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. 2 C 2018 7.1.1 1.请注意,终止空字符被认为是字符串的一部分,尽管strlen函数不计算它。

3 C 2018 7.21.6.1 8. 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. 4从技术上讲,参数应该是int类型, printf将它转换为unsigned char并使用该代码打印字符。 C 2018 7.21.6.1 8. 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"; 5 C 2018 6.3.2.1 3.用于初始化数组的字符串文字,如char x[] = "Hello"; , is also not converted to a pointer. ,也没有转换为指针。

6 C 2018 7.21.6.2 12. 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. 7即使C实现对不同类型的指针使用相同的表示,也不能保证在需要另一个指针的情况下使用一个指针类型。 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. 当编译器优化程序时,它依赖于程序的作者遵守规则,并且优化可能会以不会破坏遵循规则但破坏违反规则的程序的方式更改程序。

String is only some kind of the shorthand of the zero terminated char array . String只是zero terminated char array某种简写。 So there is no difference between the string and the "normal" array. 所以string和“普通”数组之间没有区别。

Where is real address for Stirng value?? Stirng值的真实地址在哪里?

Arrays are not pointers and they only decay to pointers. 数组不是指针,它们只会衰减到指针。 So there is no physical space in the memory where the address of the first element of the array is stored. 因此,存储器中没有物理空间存储数组的第一个元素的地址。

The main issue is &str and &str[0] have same address value. 主要问题是&str和&str [0]具有相同的地址值。

It is not the issue - array is the chunk of memory. 这不是问题 - 数组是内存的一大块。 So the address of this chunk is the same as the address of its first element. 因此,该块的地址与其第一个元素的地址相同。 The types are different. 类型不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM