c - C中字符串指针的增加值
问题描述
我正在做一个任务。我有正确的工作代码,但是,我无法理解一行的作用。
一个函数的描述是:
这个函数会 malloc 5 个字节的内存,使用 strcpy 将“bird”存储在这 5 个字节(4 个字母加上 '\0')中,并将字符串指针指向的值增加字符串的长度(使用 strlen 计算)它指向(所以它最终指向句子末尾的'\0')。然后它将返回分配的内存。
这是执行上述操作的代码
char *get_word( char **string_ptr ){
char *word;
word = malloc( 5 );
strcpy( word, "bird" );
*string_ptr += strlen( *string_ptr );
return word;
}
我不明白“*string_ptr += strlen(*string_ptr);”这行是什么 确实如此,即使有上面的描述。有人可以更详细地解释那里发生的事情吗?
解决方案
传递给的参数get_word
是char **
(大概是由于调用者传递的是字符串的地址而不是指针的集合)。
由于 C 中的所有参数都是按值传递的,因此要更改作为参数传递的指针的地址,必须传递指针的地址。否则,该函数将简单地接收指针的副本(具有它自己且非常不同的地址),并且在函数内对指针所做的任何更改都不会在调用函数中可见。
虽然您没有提供A Minimal, Complete, and Verifiable Example (MCVE),但我们可以从您的函数中推断出字符串的地址正在传递给get_word
,例如:
#define MAXC 1024
...
char buffer[MAXC] = "word_one";
char *p = buffer;
char *new_word = NULL;
...
new_word = get_word (&p);
然后稍后会在该指针的末尾附加文本(这是*string_ptr += strlen( *string_ptr );
in的目的get_word
),例如:
strcpy (p, new_word);
结果是,缓冲区现在将包含:
"word_onebird"
因此,实际上,通过将指针的地址传递给,指针前进到byget_word
中当前字的末尾,并且对指向位置的更改反映在调用函数中。string_ptr
*string_ptr += strlen( *string_ptr );
string_ptr
如果您只通过get_word(string_ptr)
,则在调用函数中所做的更改get_word
将不可见,并且那里的指针将保持不变。但是,通过传递with的地址, ( 对原始指针本身进行操作的更改会反映在调用函数中的原始指针中。string_ptr
get_word(&string_ptr)
get_word
*string_ptr = ...
通过示例了解指针
指针只是一个普通变量,它保存其他东西的地址作为它的值。换句话说,一个指针指向可以找到其他东西的地址。您通常会想到一个保存立即值的变量,例如int a = 5;
,一个指针只会保存5
存储在内存中的地址,例如int *b = &a;
。无论指针指向什么类型的对象,它的工作方式都是相同的。(一个指针,只是一个指针......)
如果需要在函数内更改指针指向的地址而不返回新指针,则必须将原始指针的地址作为参数传递,以便函数可以对原始指针本身进行操作,而不是复制如果参数采用指针本身,则该指针将出现在函数中。
一个例子可能会有所帮助。花点时间研究代码并了解原始指针如何在 中可用get_word
,但下面仅提供原始指针的副本get_word_single
:
#include <stdio.h>
#include <string.h>
#define MAXC 256
/* parameter passes only the pointer p in main() */
void get_word_single (char *string_ptr)
{
printf ("in get_word_single()\n"
" address of string_ptr: %p <-- a new pointer\n"
" value in string_ptr: %p <-- changes only seen locally\n\n",
(void*)&string_ptr, (void*)string_ptr);
string_ptr += strlen (string_ptr);
}
/* parameter passes address of p in main() */
void get_word (char **string_ptr)
{
printf ("in get_word()\n"
"address of string_ptr: %p <-- a new pointer\n"
" value in string_ptr: %p <-- holding original address\n\n"
"address of *string_ptr: %p <-- dereference to expose address\n"
" value in *string_ptr: %p <-- modify to change original\n\n",
(void*)&string_ptr, (void*)string_ptr,
(void*)&(*string_ptr), (void*)*string_ptr);
*string_ptr += strlen (*string_ptr);
}
int main (void) {
char buf[MAXC] = "one", /* a 3-character word in buf */
*p = buf;
printf ("in main()\n"
"address of p: %p <-- address of the pointer itself\n"
" value in p: %p <-- address held by the pointer\n\n",
(void*)&p, (void*)p);
get_word_single (p);
printf ("in main()\n"
"address of p: %p <-- address of pointer itself unchanged\n"
" value in p: %p <-- no change in address held\n\n",
(void*)&p, (void*)p);
get_word (&p);
printf ("in main()\n"
"address of p: %p <-- address of pointer itself unchanged\n"
" value in p: %p <-- address held incremented by 3\n\n",
(void*)&p, (void*)p);
return 0;
}
示例使用/输出
$ ./bin/passaddrex
in main()
address of p: 0x7ffc8594f370 <-- address of the pointer itself
value in p: 0x7ffc8594f380 <-- address held by the pointer
in get_word_single()
address of string_ptr: 0x7ffc8594f378 <-- a new pointer
value in string_ptr: 0x7ffc8594f380 <-- changes only seen locally
in main()
address of p: 0x7ffc8594f370 <-- address of pointer itself unchanged
value in p: 0x7ffc8594f380 <-- no change in address held
in get_word()
address of string_ptr: 0x7ffc8594f348 <-- a new pointer
value in string_ptr: 0x7ffc8594f370 <-- holding original address
address of *string_ptr: 0x7ffc8594f370 <-- dereference to expose address
value in *string_ptr: 0x7ffc8594f380 <-- modify to change original
in main()
address of p: 0x7ffc8594f370 <-- address of pointer itself unchanged
value in p: 0x7ffc8594f383 <-- address held incremented by 3
推荐阅读
- discord.js - 在命令中使用 args 的 discord.js 问题
- html - 使引导网格居中而不影响容器中项目的对称性
- c++ - 将具有多个元素的字符串作为输入并转换为向量 C++
- c - 我将如何调用二进制搜索函数来运行?
- python - Django RelatedManager:获取当前选定元素的值
- windows - Powershell在where-object子句中计算的值
- java - 如何检查活动是否已更改 Android Studio
- html - 如何删除页脚和页面底部之间的空白?
- airflow - 如何简单地导入自定义模块(带有 sql 查询的文件)
- python - 熊猫直方图有问题。当 bin 设置为 4 时,仅显示一列