我正在尝试向函数提供一个char指针,然后用它填充它,以便调用函数可以使用它。因为它总是在调用函数中给我奇怪的东西,我写了一个关于我所做的简单表示:
#include <stdio.h>
#include <stdlib.h>
void bla(char *t)
{
t = (char*) malloc(5);
if (t != 0) {
t[0] = 'h';
printf("%c\n", t[0]);
}
}
int main(int argc, char **argv)
{
char b[10];
bla(b);
printf("%c\n", b[0]);
return 1;
}
我不太确定C是否有事要做,C传递了参数的副本。我是否需要将指针传递给指针,或者是否有更好的解决方案?
编辑:
对不起伙计但我没有得到它。你能看一下这个例子:
#include <stdio.h>
#include <stdlib.h>
void blub(char **t)
{
printf("%d\n", *t);
*t = (char*) malloc(sizeof(char) * 5);
*t[0] = 'a';
*t[1] = 'b';
printf("%d\n", *t);
printf("%d\n", *t[0]);
printf("%d\n", *t[1]);
}
int main(int argc, char **argv)
{
char *a;
blub(&a);
printf("%d\n", a);
printf("%d\n", a[0]);
printf("%d\n", a[1]);
return 1;
}
输出如下:
./main
6154128
140488712
97
98
140488712
97
0 <== THIS SHOULD BE 98 AS ABOVE!?
为什么我在函数blafu中获得98,而在main中它是一个空指针?!我完全糊涂了:/
答案 0 :(得分:7)
您需要使用指针指针。
//............vv
void bla(char **t)
然后通过解除引用来使用指针:
// note the '*' in front of t
*t = (char*) malloc(5);
if (*t != 0) {
*t[0] = 'h';
printf("%c\n", *t[0]);
}
另外,将b
声明为char*
,而不是char b[10]
。
为什么呢?因为您正在尝试更改指针。逻辑与其他类型相同,但这里有点令人困惑
想一想:如果你需要传递一个int
而你需要更改它,你需要一个指向int 的指针。同样在这里 - 你需要传递指向char 的指针,你需要你改变它,所以使用&#34; 指向指向char的指针 强>&#34; :)
修改强> 的:
根据您的编辑 - 是的,您已完全理解这一点,这只是一个小问题 - operator*
和operator[]
的优先级。如果您将*t[X]
替换为(*t)[X]
,那么每个人都会没问题。)
答案 1 :(得分:2)
如果使用指向指针的指针
void blah(char **t)
你可以使用malloc作为
分配一个内存块(在头部)*t = malloc(size);
你可以这样称呼:
char *b;
bla(&b);
它将被分配并用blah填充,结果可以打印在main中。
答案 2 :(得分:1)
您正在传递指向函数的指针。通过它,你可以永久地改变(在函数返回之后)只指向它指向的对象,但你不能改变指针本身,因为它是实际传递给函数的副本。函数内的所有更改都在指针的副本上进行。当函数返回时,其原始值保持不变。
(1)如果要在某个函数中更改某个变量,则需要将其指针传递给它。如果该变量是指针类型,则传递一个指向它的指针 - 一个指向指针的指针!在您的情况下,该变量将是char **类型。
(2)如果要在函数中的堆上分配内存,则不需要使用堆栈 - 将指针b声明为char *。
(3)在堆上分配内存后,不要忘记取消分配内存,否则最终会导致内存泄漏。
(4)如果应用程序终止且没有错误,则从应用程序返回0。保留其他返回值 对于错误代码 - 如果您的应用中可能出现不同的错误,请返回不同的代码。
最后一点是这是一个纯C应用程序。在C ++中,您将使用new / delete来分配/释放内存,使用std :: string而不是char *来表示字符串,并使用std :: cout&lt;&lt;而不是printf用于将文本发送到输出流
void bla(char **pt) // (1)
{
*pt = (char*)malloc(5);
if (*pt != 0)
{
*pt[0] = 'h';
printf("%c\n", *pt[0]);
}
}
int main(int argc, char **argv)
{
char* b = 0; // (2)
bla(&b);
printf("%c\n", b[0]);
if(b)
{
free(b); // (3)
b = 0;
}
return 0; // (4)
}
答案 3 :(得分:0)
当你编写char b[10];
时,你有一个静态分配的数组,你不需要为它分配更多的空间,它最多可以容纳10 char
个值。
如果你想让你的函数修改那个数组的内容,你只需要传递一个简单的指针(但没有分配!):
void bla(char *t)
{
if (t != 0) {
t[0] = 'h';
printf("%c\n", t[0]);
}
}
在此功能之后,b
中main
的值也会发生变化。
答案 4 :(得分:0)
如果你想使用var引用返回结果,那么是的,你必须将指针传递给指针,(或者只是以通常的方式返回结果,char * bla())。不要忘记null终止符!
答案 5 :(得分:0)
第二个例子中出现奇怪行为的原因是运营商的优先级。 [](括号,数组下标)的优先级高于*(取消引用)
因此,*t[1]
与*(t[1]).
相同您需要(*t)[1]
因为t是指向char的指针:
*(t[1])
表示“取t的地址,go(sizeof(char *))字节,取消引用地址,再解除引用”
(*t)[1]
表示“取t的地址,取消引用它,go(sizeof(char))字节,然后再取消引用”
实际上在第一种情况下,行为是未定义的,因为它试图在t之后双重取消对位置的影响。在您的示例中,将始终打印第一个值,因为t [0]仅表示取消引用,因此两个案例将是相同的。