通常,如果您执行以下操作:
int * i = &someint;
它只是一个指向变量的指针。
但是,当你这样做时
char * str = "somestring";
它会自动将其转换为数组。它是执行此操作的指针,还是初始化语法的语法糖?
答案 0 :(得分:14)
不,字符串文字"somestring"
已经一个字符数组,几乎可以肯定是由编译器创建的。
该声明正在做的是将str
设置为指向第一个字符。如果您要查看底层的汇编程序代码,它可能看起来像:
str314159: db "somestring", 0 ; all string literals here.
: : : :
load r0, str314159 ; get address of string
stor r0, -24[sp] ; store it into local var str.
在很多情况下,数组会衰减到指向该数组的第一个元素的指针(有一些有限的例外,例如在执行sizeof
时)。
举例来说,以下C代码:
#include <stdio.h>
int main (void) {
char *somestr = "Hello";
puts (somestr);
return 0;
}
使用gcc -S
编译生成x86程序集时,会给我们(删除无关紧要的内容):
.LC0:
.string "Hello"
.text
.globl main
.type main, @function
main:
pushl %ebp ; Standard set up of stack frame,
movl %esp, %ebp ; aligning and making
andl $-16, %esp ; room for
subl $32, %esp ; local variables.
movl $.LC0, 28(%esp) ; Load address of string in to somestr.
movl 28(%esp), %eax ; Call puts with that variable.
movl %eax, (%esp)
call puts
movl $0, %eax ; Set return code.
leave ; Tear down stack frame and return.
ret
您可以看到第一个字符.LC0
的地址确实已加载到somestr
变量中。而且,虽然它可能不会立即明显.string
确实会创建一个由NUL字符终止的字符数组。
答案 1 :(得分:3)
它不是指向变量的指针。它是指向内存中某个位置的指针。您正在创建一个变量并将其存储在某个内存位置,然后将指针指向该位置。它适用于数组的原因是因为数组的元素背靠背存储在内存中。指针指向数组的开头。
答案 2 :(得分:2)
char * str
是指向角色的指针。将字符串分配给字符指针时,它指向字符串的第一个字符,而不是整个字符串。如果指针递增,您可以看到它指向字符串中的第二个字符。当您打印字符指针时,cout对象打印该字符并继续打印字符,直到看到空字符(\ 0)。
#include <iostream>
using namespace std;
int main()
{
char *s = "something";
cout << "before :" << s << endl;
s++;
cout << "after :" << s << endl;
}
此程序打印:
~/cpp: ./stringarray
before :something
after :omething
答案 3 :(得分:0)
int * i = &someint;
除了其他注释之外,通常我们可以说它是指向size(int)位置的指针。所以,当我们访问'i'里面的价值时。 ie * i,检索sizeof(int)内存位置。此外,算术计算以相同的方式完成。即,递增指针i + 1,递增+ sizeof(int)。因此,检索数据的大小取决于变量的“数据类型”。
答案 4 :(得分:0)
你使用“通常”这个词在这里是一个很大的问题。
我认为可能导致这种混乱的部分原因是许多函数char *
正在寻找一个c样式字符串(即空终止字符数组)。这就是他们想要的。你可以编写一个只看着角色的函数。
类似地,你可以编写一个带有int *的函数,并将其视为一个空终止数组,它只是不常见。并且有充分的理由,因为如果你想要值0怎么办?在c样式字符串中(用于显示而不是二进制数据),你永远不会想要0。
#include <iostream>
const int b_in_data[]={50,60,70,80,0};
int Display (const int * a)
{
while ( *a != 0){
std::cout << *a; ++a;
}
}
int main()
{
int a[]={20,30,40,0};
// or more like char* = something because compiler is making string literal for you
// probably somewhere in data section and replacing it with its address
const int *b = b_in_data;
Display(a);
Display(b);
return 0;
}
C样式字符串只是选择终止而不是传递大小,而B样式字符串则传递大小。 int数组通常不是空终止但可以是。归结为“正常”。
答案 5 :(得分:0)
正如人们所说str
不是一个数组而只是一个指向char的指针(第一个是“某事”,所以s)。然而,有2种语法糖
1- "something"
使用所有字符初始化一块内存,**并在末尾添加\0
。
所以
char *str = "something";
是
的语法糖char *str = {'s', 'o', 'm', 'e', 't', 'h', 'i', 'n', 'g', '\0'};
^ ^^^^^
|
+- str
技术上str
,长度不超过10个字符。(注意str
仅指向
2 -
str[5]
是
的语法糖*(str + 5)
然后,有一个约定,大多数(不是全部)C函数处理字符串,期望最后一个字符\0
(知道它结束的位置)。其他一些(见strncpy
,需要长度作为额外的参数,可以添加或不添加'\ 0'。