玩指针,被char*字符串弄得晕头转向

玩指针,被char*字符串弄得晕头转向,c,string,pointers,printf,c-strings,C,String,Pointers,Printf,C Strings,所以我在玩指针来理解不同的用例,我在这方面不是很有经验,也无法理解一些想法。我会在我有问题的地方划线。 请帮我理解指针 第6行: 为什么我不能将字符串引用为数组,因为我认为这就是它存储在内存中的方式。 如何访问字符串的单个字符 第7-8行: 当int数据类型为4字节时,&str和&str+1之间为什么有8字节的差异 第9、10和12行: 为什么使用*str引用字符串会将int作为输入? 为什么它要将一个字节char转换为int,而不是转换为4个字节 char *str = "Ninechars"

所以我在玩指针来理解不同的用例,我在这方面不是很有经验,也无法理解一些想法。我会在我有问题的地方划线。 请帮我理解指针

第6行:

为什么我不能将字符串引用为数组,因为我认为这就是它存储在内存中的方式。 如何访问字符串的单个字符

第7-8行:

int
数据类型为4字节时,
&str
&str+1
之间为什么有8字节的差异

第9、10和12行:

为什么使用
*str
引用字符串会将
int
作为输入? 为什么它要将一个字节
char
转换为
int
,而不是转换为4个字节

char *str = "Ninechars";
printf("Start\n");
printf("%s\n", str);
printf("%p\n", str);    // address of first char of str
printf("%p\n", str+1);  // address of second char of str
// printf("%s\n", str[1]);  // [segfault] warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [TODO]
printf("%p\n", &str);   // address to head of the string? NO, address of the pointer var str
printf("%p\n", &str+1); // [TODO], difference of 8bytes b/w this and previous address value? [WHY]?
printf("%d\n", *str);   // what integer is this? -> whatever can be made from 'N'=78
printf("%d\n", *(str+1));   // 'i'=105, but why is it taking single byte ints [TODO]
printf("%ld\n", sizeof(1)); // 4 bytes, as expected
// printf("%s\n", *str);    // [?]Wrong, [HOW][WHY], format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’[TODO]
printf("End\n");
输出: 开始 尼卡 0x40088f 0x400890 0x7fff95a594e8 0x7fff95a594f0 78 105 4. 终点
完整的代码文件在这里:

让我们逐行检查它:


上述地址是进程虚拟内存数据段的一部分


实际上,
str[1]=*(str+1)
。但是
%s
期望的是
字符*
,因此
(str+1)
&str[1]


&str
str
的地址,是指向
char
的指针。它在书堆上

8字节的差异意味着,在您的系统上,指向
char
的指针的大小为8字节。请尝试
printf(“\nsizeof(char*)==%zd\n”,sizeof(char*))
进行验证


这是给
N


实际上,
'i'==105
(再次),您指示
printf()
使用
%d
将其打印为
int



同样,使用
%s
printf()
需要一个字符串(
char*
,而
*str
实际上是一个
char
(一个8字节
int
)。

第6行需要一个
const char*
,您给它的是一个
char
。第12行也是如此。当您为转换说明符提供无效参数时,这是未定义的行为。不过,这可能不是你想听的。谢谢这澄清了一些问题,但为什么它会恢复为“int”?这是默认机制吗?您可能会发现有趣的。关于这一行:printf(“%s\n”,str[1]);%s需要一个字符数组的地址,但是您给了它一个字符的内容。建议:printf(“%s\n”和&str[1]);这将打印字符串的2到最后一个字符,非常感谢!再查询一次,我如何知道哪些地址属于堆栈,哪些地址属于堆?@abhik:Local变量存储在堆栈上,
malloc
'd变量存储在堆上。如果注意到打印地址的值,可以验证堆栈位于进程虚拟内存的开头,而堆位于末尾。我相信学习更多关于堆栈和堆的知识是很有趣和有教育意义的。 Output: Start Ninechars 0x40088f 0x400890 0x7fff95a594e8 0x7fff95a594f0 78 105 4 End
char *str = "Ninechars";
printf("Start\n");
printf("%s\n", str);
printf("%p\n", str);    // address of first char of str
printf("%p\n", str+1);  // address of second char of str
printf("%s\n", str[1]);
printf("%p\n", &str);   
printf("%p\n", &str+1);
printf("%d\n", *str);
printf("%d\n", *(str+1));
printf("%ld\n", sizeof(1)); // 4 bytes, as expected
printf("%s\n", *str);    // [?]Wrong, [HOW][WHY], format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’[TODO]