我知道这个问题已被多次回答,但我无法理解以下脚本。顺便说一句,我是C的新手。
当我得到它时,如果一个数组用作一个值,它代表第一个字符的地址,也就是指针。
如果我这样做:
int main (){
char quote[] = "C is great"
printf ("The quote: %s\n",quote);
printf ("The address of quote is %p\n",quote);
printf ("Size of quote is %lu\n",sizeof(quote));
}
我明白了:
The quote: C is great
The address of quote is 0x7fff06fa0d90
Size of quote is 11
所以我的问题是在所有printf情况下,我使用了相同的变量引用,但是通过更改打印类型,它如何从值更改为指针以及存储指针表示的位置,因为sizeof给出了字符串的长度。
谢谢!
答案 0 :(得分:3)
指针表示不存储在指定位置。它具有相同的存储"作为2 + 2
的结果。 (通常,这将是一个登记册)。这些在C中正式称为值;有时称为 rvalues 用于讨论目的。
如果您将quote
作为printf
的参数,则会发生转换。 %s
或%p
告诉printf是否输出所接收指针的表示,或者是否跟随该指针并打印出另一端的字符。
只要需要就形成右值。 sizeof
运算符不对其操作数执行左值到右值转换,因此sizeof(quote)
不会对指针生成或执行任何操作。
答案 1 :(得分:1)
指向类型的数组类型转换有一些例外。
除非它是
sizeof
运算符,_Alignof
运算符或一元&
运算符的操作数,或者是用于初始化数组的字符串文字,具有类型“数组类型”的类型转换为类型为“指向类型的指针”的表达式,该表达式指向数组对象的初始元素,而不是左值。
请注意声明
printf ("The address of quote is %p\n",quote);
打印quote
的第一个元素的地址,而不是quote
的地址,尽管在打印quote
的地址时您将获得相同的地址值。
请注意草稿中提到的_Alingof
是错误的。
答案 2 :(得分:0)
在内部,指针是一个保存地址的整数值。因此,在所有情况下,您都将此指针值传递给printf()
。
但格式说明符决定了printf()
对该指针的作用。在一种情况下,它读取指针中包含的地址处的字符。在另一种情况下,它只是打印指针值。
答案 3 :(得分:0)
所有变量都是指向C中内存位置的指针。没有别的。编译器通过指针跟踪变量。它还跟踪变量类型和大小,但这些并不严格。保证每个变量都有一个指针,但是可以改变类型和大小。
类型和大小决定了在程序中使用变量时表示的值,但就程序而言,它实际上不知道每个指针存储的是什么,除了编译器已经专门编写它进入你的编译程序。
您可以使用强制转换来覆盖类型(如果您不小心,甚至可以读取超出范围的内存)。如果您有一个包含12个字符的数组,则可以根据需要将值读取为3个整数的数组。
对于静态数组(如您的示例),无论是定义数组的大小还是将值赋给数组,编译器都会分配所需的内存。
它知道长度要么是因为你在定义中明确地告诉它(char quote[11]
),要么因为它知道数组中存储了什么("C is great"
= 10)。由于char类型变量是1个字节,因此其中10个必须是10个字节。
你的数组实际上是11个字节。这是因为您分配的方式和内容。在C中,当编译器找到字符串文字时,它会自动在末尾附加NULL
个字符。如果它没有这样做,printf
之类的函数就不会知道字符串的长度。它不会知道,因为大小和类型不与变量一起存储。
如果您将数组编写为:
char quote[] = {'C',' ','i','s',' ','g','r','e','a','t'};
编译器不会知道它是一个字符串而你的数组将是10个字节而不是11个。在这种情况下,当你尝试将printf
作为字符串时,它也可能表现得很奇怪,因为printf
依赖于NULL
字节来知道它何时到达字符串的末尾。
printf ("The quote: %s\n",quote);