什么';c中带数组的指针有什么不同?

什么';c中带数组的指针有什么不同?,c,pointers,C,Pointers,我试图用谷歌搜索这个话题,但没人能解释清楚。我尝试以下代码: #include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char * argv[]){ char * p1 = "dddddd"; const char * p2 = "dddddd"; char p3[] = "dddddd"; char * p4 =(char*

我试图用谷歌搜索这个话题,但没人能解释清楚。我尝试以下代码:

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

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

    char * p1 = "dddddd";
    const char * p2 = "dddddd";
    char p3[] = "dddddd";
    char * p4 =(char*)malloc(sizeof("dddddd")+1);
    strcpy(p4, "dddddd");
    //*(p1+2) = 'b'; // test_1
    //Output >>  Bus error: 10

    // *(p2+2) = 'b'; // test_2
    // Output >> char_point.c:11:13: error: read-only variable is not assignable
    *(p3+2) = 'b'; // test_3
    // Output >>
    //d
    //dddddd
    //dddddd
    //ddbddd

    *(p4+2) = 'k'; // test_4
    // Output >>
    //d
    //dddddd
    //dddddd
    //ddbddd
    //ddkddd

    printf("%c\n", *(p1+2));
    printf("%s\n", p1);
    printf("%s\n", p2);
    printf("%s\n", p3);
    printf("%s\n", p4);

    return 0;
}

我想知道每个指针我声明了什么,它是哪一部分?

数组是常量指针,这意味着数组指向内存地址,您不能更改它指向的是哪个部分。但是你可以改变其中的元素

虽然可以更改指针指向的位置,但它的元素是常量

例如,考虑这个代码

int main(){
int a[] = {1,2,3};
int * ptr = {1,2,3};

//a[0] == *(a+0)
//a[1] == *(a+1)

a += 1; // this is wrong, because we cant change were array points
ptr += 1; // this is correct, now the pointer ptr will points to the next element which is 2

a[0] += 2 // this is correct, now a[0] will become 3
*ptr += 2 // this is wrong, because we cant change the elements of the pointer.
return 0;
    }

数组是常量指针,这意味着数组指向内存地址,并且您不能更改它的指向。但是你可以改变其中的元素

虽然可以更改指针指向的位置,但它的元素是常量

例如,考虑这个代码

int main(){
int a[] = {1,2,3};
int * ptr = {1,2,3};

//a[0] == *(a+0)
//a[1] == *(a+1)

a += 1; // this is wrong, because we cant change were array points
ptr += 1; // this is correct, now the pointer ptr will points to the next element which is 2

a[0] += 2 // this is correct, now a[0] will become 3
*ptr += 2 // this is wrong, because we cant change the elements of the pointer.
return 0;
    }
所以

这应该是

const char * p1 = "dddddd";
字符串文字(引号中的文字)驻留在只读内存中。即使你 不要在变量声明中使用
const
关键字,
p1
still 指向只读内存。所以

*(p1+2) = 'b'; // test_1
他会失败的

这里

编译器告诉您,您不能这样做,因为您将
p2
声明为
const
。 第一个测试和这个测试的区别在于,代码试图 修改字符失败

现在:

char * p4 =(char*)malloc(sizeof("dddddd")+1);
首先,不要投出
malloc
&好友。第二步:
sizeof
-运算符返回 在内存中存储表达式所需的字节数<代码>“ddddd”是一个字符串 literal,它返回指向
char
的指针,因此
sizeof(“dddddd”)
返回数字 指向
char
的指针需要存储在内存中的字节数

正确的功能应该是strlen:

char * p4 = malloc(strlen("dddddd")+1);
注意,在这种情况下

char txt[] = "Hello world";
printf("%lu\n", sizeof(txt));
将打印12而不是11。C字符串以
'\0'
结尾,这意味着
txt
保存所有这些字符加上
'\0'
-终止字节。在这种情况下
sizeof
不返回指针的字节数,因为
txt
是一个 数组

在这里,你不会得到像以前一样的12码,很可能是8码(今天的普通码) 指针)。尽管
bar
中的
txt
是一个数组,但
foo
中的
txt
是一个数组 指针。

So

这应该是

const char * p1 = "dddddd";
字符串文字(引号中的文字)驻留在只读内存中。即使你 不要在变量声明中使用
const
关键字,
p1
still 指向只读内存。所以

*(p1+2) = 'b'; // test_1
他会失败的

这里

编译器告诉您,您不能这样做,因为您将
p2
声明为
const
。 第一个测试和这个测试的区别在于,代码试图 修改字符失败

现在:

char * p4 =(char*)malloc(sizeof("dddddd")+1);
首先,不要投出
malloc
&好友。第二步:
sizeof
-运算符返回 在内存中存储表达式所需的字节数<代码>“ddddd”是一个字符串 literal,它返回指向
char
的指针,因此
sizeof(“dddddd”)
返回数字 指向
char
的指针需要存储在内存中的字节数

正确的功能应该是strlen:

char * p4 = malloc(strlen("dddddd")+1);
注意,在这种情况下

char txt[] = "Hello world";
printf("%lu\n", sizeof(txt));
将打印12而不是11。C字符串以
'\0'
结尾,这意味着
txt
保存所有这些字符加上
'\0'
-终止字节。在这种情况下
sizeof
不返回指针的字节数,因为
txt
是一个 数组

在这里,你不会得到像以前一样的12码,很可能是8码(今天的普通码) 指针)。尽管
bar
中的
txt
是一个数组,但
foo
中的
txt
是一个数组 指针。

“为什么不能修改
p1
?” 粗略地说,
p1
指向一个字符串文本,试图修改字符串文本会导致C中未定义的行为

更具体地说,根据上下文,字符串文字是:

用于初始化静态存储持续时间和长度刚好足以包含序列的数组。对于字符串文字,数组元素的类型为
char

关于具有
静态
存储持续时间的对象

所有具有静态存储持续时间的对象应在程序启动前初始化(设置为其初始值)。此类初始化的方式和时间另行规定

“内存的哪个部分是布局?” 但是,该标准没有指定实现必须遵循的任何特定内存布局

标准对从字符串文本创建的
char
数组的说明是():

如果这些数组的元素具有适当的值,则未指定这些数组是否不同如果程序试图修改这样的数组,则行为未定义。

“为什么不能修改
p1
?” 粗略地说,
p1
指向一个字符串文本,试图修改字符串文本会导致C中未定义的行为

更具体地说,根据上下文,字符串文字是:

用于初始化静态存储持续时间和长度刚好足以包含序列的数组。对于字符串文字,数组元素的类型为
char

关于具有
静态
存储持续时间的对象

所有具有静态存储持续时间的对象应在程序启动前初始化(设置为其初始值)。此类初始化的方式和时间另行规定

“内存的哪个部分是布局?” 但是,该标准没有指定实现必须遵循的任何特定内存布局

标准对从字符串文本创建的
char
数组的说明是():

这是不具体的