我正在使用带有指针的malloc()
来练习分配内存,但有一个关于指针的观察是,为什么strcpy()
可以在没有str
的情况下接受*
变量:
char *str;
str = (char *) malloc(15);
strcpy(str, "Hello");
printf("String = %s, Address = %u\n", str, str);
但是对于整数,我们需要*给str一个值。
int *str;
str = (int *) malloc(15);
*str = 10;
printf("Int = %d, Address = %u\n", *str, str);
我真的很困惑strcpy()
接受str
的原因,因为根据我自己的理解,"Hello"
将被传递到str
的内存位置,这将导致一些错误。
答案 0 :(得分:4)
在C中,字符串(根据定义)是一个字符数组。但是(无论我们是否一直都在意识到),我们几乎总是使用指针访问数组。因此,尽管C没有真正的“字符串”类型,但对于大多数实际用途,类型指针指向char(即char *
)就是为此目的。几乎任何接受或返回字符串的函数都会使用char *
。这就是strlen()
和strcpy()
接受char *
的原因。这就是printf %s
期望char *
的原因。在所有这些情况下,这些函数需要的是指向字符串第一个字符的指针。 (然后他们按顺序读取字符串的其余部分,当他们找到终止'\0'
字符时停止。)
在这些情况下,您不使用明确的*
字符。 *
只会提取指向的字符(即字符串的第一个字符),但是你不想提取第一个字符,你想要提交整个字符串(即指向整个字符串)到strcpy
所以它可以完成它的工作。
在你的第二个例子中,你根本没有使用字符串。 (你使用名为str
的变量的事实让我困惑了一会儿。)你有一个指向一些int的指针,你正在使用指向的第一个int。由于您直接访问指向的内容之一,因此您需要明确的*
字符。
答案 1 :(得分:1)
*
称为间接或解除引用运算符。
在你的第二个代码中,
*str = 10;
将值 10分配给str
指向的内存地址。这是一个值(即单个变量)。
OTOTH,strcpy()
一次复制整个字符串。它接受两个char *
参数,因此您不需要*
取消引用以在传递参数时获取值。
您可以使用取消引用运算符(不使用strcpy()
)逐个元素复制,例如
char *str;
str = (char *) malloc(15); //success check TODO
int len = strlen("Hello"); //need string.h header
for (i = 0; i < len; i ++)
*(str+i)= "Hello"[i]; // the * form. as you wanted
str[i] = 0; //null termination
答案 2 :(得分:0)
按惯例和设计,许多字符串操作函数(包括strcpy
)接受指向数组第一个字符的指针,而不是指向整个数组的指针,即使它们的值是一样的。
这是因为他们的类型是不同的;例如指向char[10]
的指针与指向char[15]
的指针的类型不同,并且将指针传递给整个数组将是不可能或非常笨拙的,因为这样,除非你将它们转移到任何地方或制作不同长度的不同功能。
出于这个原因,他们建立了一个约定,即传递一个字符串,其指针指向其第一个字符,而不是整个数组,必要时可能还有它的长度。许多在数组上运行的函数(例如memset
)的工作方式相同。
答案 3 :(得分:0)
嗯,这是第一个片段中发生的事情:
您首先动态分配15个字节的内存,将此地址存储到char指针,该指针是指向1字节数据序列(字符串)的指针。
然后调用strcpy()
,它遍历字符串并将字符(每字节字节)复制到新分配的内存空间中。每个字符都是基于ASCII表的数字,例如。字符a = 97(看看man ascii
)。
然后将此地址传递给printf()
,该字符串从字符串读取,每字节字节数,然后将其刷新到终端。
在第二个片段中,进程是相同的,您仍然分配15个字节,将地址存储在int *指针中。 int是4字节数据类型。
执行*str = 10
时,您将取消引用指针,将值10存储在str指向的地址处。提醒我之前写的内容,你可以做* str ='a',这个索引0整数的值是97,即使你试着把它读成int。如果愿意,你可以打印事件。
为什么strcpy()
可以将int *
作为参数?因为它是一个可以写入的内存空间,每字节字节数。你可以将“地狱”存储在一个int中,然后“o!”在下一个。
这就是使用简易性。
答案 4 :(得分:0)
请参阅=
运算符与函数strcpy
之间存在差异。
*
是deference运算符。当你说*str
时,它表示str指向的内存位置的值。
同样作为一种好习惯,请使用此
str = (char *) malloc( sizeof(char)*15 )
这是因为不同平台上数据类型的大小可能不同。因此,使用sizeof
函数来确定其在运行时的实际大小。