为什么sizeof(*指针)的输出为1? #包括 int main() { char*str1=“Abcde”; 字符str2[]=“Abcde”; printf(“sizeof(str1)=%d,sizeof(str2)=%d sizeof(*str1)=%d”, sizeof(str1)、sizeof(str2)、sizeof(*str1)); 返回0; }
上述代码给出了为什么sizeof(*指针)的输出为1? #包括 int main() { char*str1=“Abcde”; 字符str2[]=“Abcde”; printf(“sizeof(str1)=%d,sizeof(str2)=%d sizeof(*str1)=%d”, sizeof(str1)、sizeof(str2)、sizeof(*str1)); 返回0; },c,arrays,string,pointers,C,Arrays,String,Pointers,上述代码给出了sizeof(*str1)=1的输出。有人能解释一下为什么我希望它是sizeof(“Abcde”),因为它是去引用的。因为*str1是字符 字符是一个字节 一个字节的大小为1。sizeof(*str1)是1,因为: str1是一个char* *str1是一个字符 根据定义,char的大小为1 一旦您将“Abcde”分配给字符*,您就失去了原始字符串的所有上下文,包括其大小。有两种语法形式的sizeof: sizeof(TYPE),其中TYPE是一种类型(例如int,char,等等
sizeof(*str1)=1的输出。有人能解释一下为什么我希望它是sizeof(“Abcde”)
,因为它是去引用的。因为*str1
是字符
字符是一个字节
一个字节的大小为1。sizeof(*str1)
是1
,因为:
str1
是一个char*
*str1
是一个字符
根据定义,char
的大小为1
一旦您将“Abcde”
分配给字符*
,您就失去了原始字符串的所有上下文,包括其大小。有两种语法形式的sizeof
:
sizeof(TYPE)
,其中TYPE是一种类型(例如int
,char
,等等)
sizeof expr
,其中expr
是任何表达式(如1
或*ptr
等)
注意第二种形式中没有()
!在任何情况下,都不会对类型
或表达式
进行评估(如标准所述:仅针对其大小
)
注意:还有第三种(隐藏)形式:
对象的大小
;其中object是某个标识符
在下列情况下:
#include <stdio.h>
int main()
{
char *str1 = "Abcde";
char str2[] = "Abcde";
printf("sizeof(str1) = %d, sizeof(str2) = %d sizeof(*str1) = %d",
sizeof(str1), sizeof(str2),sizeof(*str1));
return 0;
}
,则sz
将为123
,因此buff
不会升级/降级为指针
注意:sizeof
运算符具有很强的优先级(请检查表!),因此
sz将等于sizeof(int)+2
在您的例子中,*str
将是一个a字符,值为“a”:其大小将是一个:字符大小
仅此而已。其他答案正确地解释了为什么sizeof(*str)==1
,但它们不能解决您可以理解的困惑
C数组在某种意义上是二等公民。数组对象是实际对象,与任何其他类型(整数、结构等)的对象一样,但该语言提供的直接操作数组的操作很少
相反,数组对象通常通过指向其元素的指针进行操作
在您的示例中,您有:
sz = sizeof 1+2;
字符串literal“Abcde”
对应于类型为char[6]
的匿名数组对象(5表示字符串长度加1表示终止的'\0'
空字符)。因此,sizeof“Abcde”==6
但是str1
不是指向该数组对象的指针;它只是指向其初始元素的指针,其中包含字符'a'
。如果我们想访问数组的其他元素(字符'b'
,'c'
,等等),我们需要执行指针算法,使指针通过数组对象的元素
所以最初,*str1=='A'
--但在++str1
之后,*str1=='b'
如果要打印字符串的值,可以执行以下操作:
char *str1 = "Abcde";
而printf
函数将在内部执行通过字符串字符所需的指针算法
这就是为什么sizeof(*str)==1
。它只指向数组对象的单个元素。我们可以使用它来访问其他元素,但是指针值本身并不包含关于数组大小的任何信息。(这就是终止'\0'
的目的,因此我们可以在不预先知道字符串有多大的情况下识别字符串的结尾。)
请注意,您可以有一个指向整个数组对象的指针:
printf("%s\n", str1);
和sizeof*array\u ptr==6
——但这并不像您预期的那样有用array\u ptr
只能指向正好由6个元素组成的数组,而且由于像printf
和strlen
这样的函数需要char*
指针,因此不能使用array\u ptr
直接操作数组。(在处理多维数组时,数组对象的指针确实会出现——数组的数组。)
相对于整个数组对象,指向数组元素的指针更加灵活,标准库广泛使用它们。缺点是您必须自己跟踪数组的大小,例如,通过将其作为额外参数传递,或使用哨兵值(如'\0'
)来标记数组的结尾。因为*str
是一个字符,而字符的大小定义为1。@wildplasser的答案以有趣的名称命名“answer section”mate通过写入*str引用存储在str所指地址中的值,该地址是大小为1(字节)的字符。这可能会让人困惑,但您的指针是str1
。当您声明和初始化指针时char*str1=“Abcde”
是类型(指向字符的指针)。您可以执行char*str1;
然后执行str1=“Abcde";代码>如果这有助于强调指针是什么。此后,当您取消对指针的引用时,例如*str1
,您删除了一级间接寻址,因此取消对char的引用只会留下typechar
。这里介绍了数组/指针转换:打印size\u t
值(例如sizeof
表达式的值)的正确格式是“%zu”
,而不是“%d”
。使用“%d”
可能有效,也可能无效,具体取决于实现。(一些较旧的实现不支持“%zu”
;如果是这种情况,您可以将其转换为已知类型:printf(“%lu\n”,(无符号长)sizeof where);
在第二种形式中指出括号的缺失,尽管这是技术性的
printf("%s\n", str1);
char (*array_ptr)[6] = &"Abcde";