c - 将字符串文字与数组分配给 char

标签 c pointers initialization scalar braced-init-list

我有一个 char pointer像这样的字符串文字 char *d="abc";我正在增加它

*(d+1)
我得到类似 b 的信息如果我这样做 printf("%c",*(d+1))但是当我有这些线
char *c={'a','b','c'}
printf("%c\n",*(c+1)); /// CAUSES SegFault
上面的行抛出异常。当我尝试使用 gdb 进行回溯并打印 *(c+1) 时,它说 $1 = 0x61 <error: Cannot access memory at address 0x61>所以我的问题是为什么这与我将字符串文字分配给 char pointer 相比不起作用
当我分配 int 数组时也会发生同样的情况至 int pointer并以这种方式增加它

最佳答案

主要感谢@nielsen 指出这一点,在他们发表评论后,一切都变得清晰起来。
首先,让我们尝试一个不会出现段错误的类似程序:

#include <stdio.h>

int main()
{
    char *a = {'a', 'b', 'c'};
    printf("%p\n", (void *) a);
}
对我来说,这输出:0x61 .这应该会响起,它与 GDB 提供的地址相同。
然而,更重要的是我收到的警告:
main.c:5:16: warning: initialization makes pointer from integer without a cast [-Wint-conversion]                                                           
     char *a = {'a', 'b', 'c'};                                                                                                                             
                ^~~                                                                                                                                         
main.c:5:16: note: (near initialization for ‘a’)                                                                                                            
main.c:5:21: warning: excess elements in scalar initializer                                                                                                 
     char *a = {'a', 'b', 'c'};

main.c:5:16: warning: initialization makes pointer from integer without a cast [-Wint-conversion]                                                           
     char *a = {'a', 'b', 'c'};                                                                                                                             
                ^~~                                                                                                                                         
main.c:5:16: note: (near initialization for ‘a’)                                                                                                            
main.c:5:21: warning: excess elements in scalar initializer                                                                                                 
     char *a = {'a', 'b', 'c'};

main.c:5:21: warning: excess elements in scalar initializer                                                                                                 
     char *a = {'a', 'b', 'c'};                                                                                                                             
                     ^~~                                                                                                                                    
main.c:5:21: note: (near initialization for ‘a’)                                                                                                            
main.c:5:26: warning: excess elements in scalar initializer                                                                                                 
     char *a = {'a', 'b', 'c'};                                                                                                                             
                          ^~~                                                                                                                               
main.c:5:26: note: (near initialization for ‘a’)
initialization makes pointer from integer without a cast [-Wint-conversion]已经在评论中指出了。然而,有了另一个警告,这变得很清楚:
main.c:5:21: warning: excess elements in scalar initializer                                                                                                 
     char *a = {'a', 'b', 'c'};                                                                                                                             
                     ^~~                                                                                                                                    
main.c:5:21: note: (near initialization for ‘a’)                                                                                                            
main.c:5:26: warning: excess elements in scalar initializer                                                                                                 
     char *a = {'a', 'b', 'c'};
基本上,这不会像你认为的那样做。在所有。 {}是一个“标量”初始化器。来自 https://en.cppreference.com/w/c/language/type ,这是摘录:

scalar types: arithmetic types and pointer types


指针恰好是标量类型,因为它只能保存 1 个值,即地址。所以编译器只会使用 'a'初始化 cc只能保存 1 个值,并忽略其他所有内容(因为再次是标量)。 'a'的ASCII值是多少十六进制? 61,与 GDB 指出的地址完全相同。希望你明白现在发生了什么:
  • 当编译器看到 char *c = {'a', 'b', 'c'}; ,它将聚合初始值设定项视为标量初始值设定项,因为 c是标量变量,所以只需要 'a'并告诉你不要添加 2 个额外的字符。
  • 'a' , int文字,隐式转换为 char *它变成了一个地址。编译器也会就此警告您。
  • 您尝试打印 *(c + 1) ,但由于这是一个无效地址/您不允许触摸该地址,因此会发生段错误。

  • 我认为你真正想做的是治疗c作为数组。为此,您可以更改 c的类型到一个数组:
    char c[] = {'a', 'b', 'c'};
    
    或保留 c作为 char *并使用复合文字:
    char *c = (char []) {'a', 'b', 'c'};
    

    然而,char *c = {'a', 'b', 'c'};不是有效的 C,因为花括号括起来的标量初始值设定项只允许保存 1 个表达式。弗拉德的回答给出了证明这一点的标准的具体引述。使用 -pedantic-errors 编译此代码将用错误替换此处提到的所有警告。

    关于c - 将字符串文字与数组分配给 char,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67278604/

    相关文章:

    Python numpy 屏蔽数组初始化

    c - 为什么 "sys_clone"定义在 "./arch/h8300/kernel/process.c"中?

    c - 模块化 C 开发的最佳实践是什么

    c - 字符集/位串的减法运算

    c - 程序测试很好,但从菜单调用时会出现未初始化的错误。 C

    java - 错误: Variable might not have been initialized?

    c - Epoch和wireshark捕获

    c++ - 在两个相同类的指针之间进行转换的安全性?

    c++ - 使用 std::map::extract 修改键

    c++ - 由于类型不匹配,无法将一个指针分配给另一个指针,或者编译器这样说