Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c-递增数组指针_C_Arrays_Pointers - Fatal编程技术网

c-递增数组指针

c-递增数组指针,c,arrays,pointers,C,Arrays,Pointers,有人能给我解释一下为什么这样不行吗。我是java开发人员,不熟悉c/c++ 据我所知,数组的指针实际上是数组第一个元素的指针,对吗 void test(char *tmp) { test2(tmp); //*tmp++ = '1'; //*tmp++ = '2'; *tmp++ = '3'; *tmp++ = '4'; *tmp = 0; } void test2(char *tmp) { *tmp++ = '1'; *tmp++

有人能给我解释一下为什么这样不行吗。我是java开发人员,不熟悉c/c++
据我所知,数组的指针实际上是数组第一个元素的指针,对吗

void test(char *tmp)
{
    test2(tmp);
    //*tmp++ = '1';
    //*tmp++ = '2';
    *tmp++ = '3';
    *tmp++ = '4';
    *tmp = 0;
}

void test2(char *tmp)
{
    *tmp++ = '1';
    *tmp++ = '2';
}

int main(int argc, char **argv)
{
    char tmp[5];
    test(tmp);
    printf("%s", tmp);
    return 0;
}
仅打印
34
。当我在函数
test2
中调试此代码时,
tmp
的指针增加1,但在调用test2后返回函数
test
中,
tmp
的指针返回其初始值。
如果我将所有代码放在一个函数中,就像这样,它可以工作:

void test(char *tmp)
{
    *tmp++ = '1';
    *tmp++ = '2';
    *tmp++ = '3';
    *tmp++ = '4';
    *tmp = 0;
}

最后一行上的
*tmp=0
还有什么作用。我从其他代码中复制了它。如果没有它,数组的末尾会有一些垃圾。

增加test2()中的“tmp”不会增加test()中的“tmp”。在test2()调用返回后,test2编写的“1”和“2”将被“3”和“4”覆盖


零是“\0”c样式的“字符串”终止符。

在函数
test2
中,通过指针意味着您可以修改tmp指向的内容,但
test2
不会修改指针本身

void test2(char *tmp)
{
    *tmp++ = '1';
    *tmp++ = '2';
}
因此,在调用函数
test
中,调用
test2
后,指针不会像预期的那样向前移动2个位置,而是
tmp
保持不变(指向数组的第一个值)。因此,实际发生的是
test2
为前两个元素分配
1
2
,然后
test
3
4
覆盖这两个值

void test(char *tmp)
{
    test2(tmp);
    *tmp++ = '3';
    *tmp++ = '4';
    *tmp = 0;
}
最后一行上的*tmp=0也是做什么的


这是字符串终止符。

如果在1个函数中写入所有函数,则得到1234,这是正常的,但如果写入2个函数时始终传递相同的指针,则第二个函数将覆盖第一个函数已经完成的操作

test:
tmp -> Point to [100]
call test2 giving [100] as parameter
write 3 in [100]
increment pointer from [100] to [101]
write 4 in [101]
increment pointer from [101] to [102]

test2:
tmp -> Point to [100]
write 1 in [100]
increment pointer from [100] to [101]
write 2 in [101]
increment pointer from [101] to [102]

现在我想您可以看到错误。

函数参数是它的局部变量。参数通过值传递给函数,这意味着传递参数的副本

因此,在函数
test2
中,使用了函数
test
的指针
tmp
的副本。对象副本的任何更改都不会影响对象本身

test2的调用可以想象如下方式

void test(char *tmp)
{
//  test2(tmp);
    char *new_ptr = tmp;
    test2( new_ptr );
//  ...
}

void test2(/*char *tmp*/)
{
    char *tmp = new_ptr;
    *tmp++ = '1';
    *tmp++ = '2';
}
如果您将
test2
的参数声明为指针的引用,那么在这种情况下,指针本身可以更改。比如说

void test(char *tmp)
{
    test2( &tmp );
    //     ^^^^
    //*tmp++ = '1';
    //*tmp++ = '2';
    *tmp++ = '3';
    *tmp++ = '4';
    *tmp = 0;
}

void test2(char **tmp)
//         ^^^^^^^^^^
{
    *( *tmp )++ = '1';
    *( *tmp )++ = '2';
}
对于数组,表达式中使用的数组(很少有例外,例如在运算符
sizeof
中使用数组)被隐式转换为指向其第一个元素的指针

例如,如果您有一个类型为
T

T a[N];
那么下面的声明

T *p = a;
有效,指针由数组
a
的第一个元素的地址初始化

另一个例子

char *s = "Hello";
下面是字符串literal
“Hello”
在表达式中用作初始值设定项。包含终止零
'\0'
的字符串文本的类型为
char[6]
,隐式转换为指向其第一个字符
'H'
的指针

<>在C++字符串中有固定字符数组的类型。因此,C++中的字符串文字<代码>“hello”<代码>具有类型<代码> const char(6)< /C> > /P> 在C++中,你必须写< /P>
const char *s = "Hello";

但在这两种语言中,字符串文字是不可变的。

0是nul终止符,字符串以0或nul字节结尾,因此printf()之类的函数知道字符串的结尾,因为-一段字符串有多长

由于您正在将指针传递给test2(),test2()正在递增指针-但实际上并没有将更改/递增的指针传递回调用函数…就test()而言,指针没有更改,因此后续的更改将覆盖以前的更改

#include <stdio.h>
#include <stdlib.h>

char *test2(char *tmp)
{
   *tmp++ = '1';
   *tmp++ = '2';

   return tmp;
}

void test(char *tmp)
{
    tmp = test2(tmp);

    //*tmp++ = '1';
    //*tmp++ = '2';
    *tmp++ = '3';
    *tmp++ = '4';
    *tmp = 0;
}

int main(int argc, char **argv)
{
    char tmp[5];

    test(tmp);
    printf("%s", tmp);

    return 0;
}
#包括
#包括
char*test2(char*tmp)
{
*tmp++='1';
*tmp++='2';
返回tmp;
}
无效测试(字符*tmp)
{
tmp=test2(tmp);
//*tmp++='1';
//*tmp++='2';
*tmp++='3';
*tmp++='4';
*tmp=0;
}
int main(int argc,字符**argv)
{
char-tmp[5];
试验(tmp);
printf(“%s”,tmp);
返回0;
}
这里test2将更改/增加的指针返回给调用者,tess()将接收更新的字符。由于要在末尾添加0或nul字节,因此这里需要至少包含5个元素的数组


上面的代码应该可以正常工作。

1。字符串以null结尾(因此
*tmp=0
)。2.通过使用
tmp[0]=
等方法使代码可读。Ed Heal可以工作,这是我尝试的第一件事,但我不希望
test
依赖于
test2
。例如,如果我在
test2
3次中增加tmp,我希望在测试中从前面继续。这可能吗?@dasblinkenlight fixed如果我有4个元素,我是否需要创建大小为5的数组?@pedja是的,如果字符串中有四个字母,则需要一个包含五个
char
s的数组来容纳空终止符。那么,如果不显式指定数组索引,我怎么做呢?例如
tmp[0]
tmp[1]
等。一种方法是从test2()返回指针:'char*test2(char*tmp)'…'返回tmp;'从temp中将其命名为:“tmp=test2(tmp);”好的,我现在明白了,但是我怎样才能使它像这样工作,而不使用
tmp[0]
tmp[1]
等等