char*和char**之间的区别(在C中)

yot*_*moo 7 c string pointers

我写的这段代码很简单

#include <stdio.h>
#include <string.h>

void printLastLetter(char **str)
{
    printf("%c\n",*(*str + strlen(*str) - 1));
    printf("%c\n",**(str + strlen(*str) - 1));
}

int main()
{
    char *str = "1234556";
    printLastLetter(&str);
    return 1;
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我想打印字符串中的最后一个字符,我知道printLastLetter的第一行是正确的代码行.我不完全理解的是*str和**str之间的区别.第一个是字符数组,第二个是?另外,char*str和str [10]之间的内存分配有什么不同?Thnks

MBy*_*ByD 20

char*是指向char char **的指针,是指向char的指针.

char *ptr; 不为字符分配内存,它为指向char的指针分配内存.

char arr[10];分配10个字符并arr保存第一个字符的地址.(虽然arr不是指针(不是char *)而是类型char[10])

用于演示:char *str = "1234556";如:

char *str;         // allocate a space for char pointer on the stack
str = "1234556";   // assign the address of the string literal "1234556" to str
Run Code Online (Sandbox Code Playgroud)

正如@Oli Charlesworth评论的那样,如果你使用一个指向常量字符串的指针,比如上面的例子,你应该将指针声明为const- const char *str = "1234556";所以如果你试图修改它,这是不允许的,你将得到一个编译时错误而不是运行时访问冲突错误,例如分段错误.如果您对此不熟悉,请查看此处.

另请参阅新闻组comp.lang.c的常见问题解答.


Jam*_*rty 11

char**x是指向指针的指针,当您想要修改其范围之外的现有指针(例如,在函数调用中)时,它非常有用.

这很重要因为C是通过复制传递的,所以要修改另一个函数中的指针,你必须传递指针的地址并使用指向指针的指针,如下所示:

void modify(char **s)
{
  free(*s); // free the old array
  *s = malloc(10); // allocate a new array of 10 chars
}

int main()
{
  char *s = malloc(5); // s points to an array of 5 chars
  modify(&s); // s now points to a new array of 10 chars
  free(s);
}
Run Code Online (Sandbox Code Playgroud)

您还可以使用char**来存储字符串数组.但是,如果您动态分配所有内容,请记住跟踪字符串数组的长度,以便循环遍历每个元素并释放它.

至于你的上一个问题,char*str; 简单地声明一个没有分配内存的指针,而char str [10]; 在本地堆栈上分配10个字符的数组.一旦它超出范围,本地数组将消失,这就是为什么如果你想从函数返回一个字符串,你想要使用一个带有动态分配(malloc'd)内存的指针.

另外,char*str ="一些字符串常量"; 也是一个指向字符串常量的指针.字符串常量存储在已编译程序的全局数据部分中,无法修改.您不必为它们分配内存,因为它们已编译/硬编码到您的程序中,因此它们已占用内存.