C++ 是什么让一个字符*一个字符数组?
通常,如果您执行以下操作:C++ 是什么让一个字符*一个字符数组?,c++,c,arrays,pointers,char,C++,C,Arrays,Pointers,Char,通常,如果您执行以下操作: int*i=&someint 它只是一个指向变量的指针 但是,当你这样做的时候 char*str=“somestring” 它会自动将其转换为数组。是指针在执行此操作,还是只是初始化语法的语法糖?不,字符串文字“somestring”已经是一个字符数组,几乎可以肯定是由编译器创建的 该语句所做的是将str设置为指向第一个字符。如果要查看底层汇编程序代码,它可能会如下所示: str314159: db "somestring", 0 ; all string l
int*i=&someint代码>
它只是一个指向变量的指针
但是,当你这样做的时候
char*str=“somestring”代码>
它会自动将其转换为数组。是指针在执行此操作,还是只是初始化语法的语法糖?不,字符串文字“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;
}
您可以看到,第一个字符.LC0
的地址确实已加载到somestr
变量中。而且,虽然它可能不是很明显。。string
确实创建了以NUL字符结尾的字符数组。它不是指向变量的指针。它是指向内存中某个位置的指针。您正在创建一个变量并将其存储在某个内存位置,然后将指针指向该位置。它对数组有效的原因是数组的元素背靠背存储在内存中。指针指向数组的开头
char * str
是指向字符的指针。将字符串指定给字符指针时,它将指向字符串的第一个字符,而不是整个字符串。如果指针递增,您可以看到它指向字符串中的第二个字符。打印字符指针时,cout对象打印字符并继续打印字符,直到看到空字符(\0)
除了其他注释外,一般来说,我们可以说它是指向大小位置(int)的指针。所以,当我们访问“i”中的值时。即,检索sizeof(int)内存位置。同样,算法计算也是以同样的方式进行的。即,增加指针i+1,增加+sizeof(int)。因此,检索数据的大小取决于变量的“数据类型”。您使用的“正常”一词在这里是一个很大的问题
我认为造成这种混乱的部分原因是,许多使用char*
的函数正在寻找c风格的字符串(即以null结尾的字符数组)。这就是他们想要的。您可以编写一个函数,只查看字符
类似地,您可以编写一个接受int*并将其视为以null结尾的数组的函数,但这并不常见。有充分的理由,因为如果你想要值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;
}
#包括
const int b_in_data[]={50,60,70,80,0};
整数显示(常数整数*a)
{
而(*a!=0){
正如人们所说,std::coutstr
不是一个数组,而只是一个指向字符的指针(something的第一个,所以是s)
1-“某物”
用所有字符初始化内存块,**并在末尾添加\0
。
所以
合成糖对人体有益吗
char *str = {'s', 'o', 'm', 'e', 't', 'h', 'i', 'n', 'g', '\0'};
^ ^^^^^
|
+- str
所以从技术上讲,str
,是10个字符,而不是9个。(注意,str
只指向
2-
合成糖对人体有益吗
*(str + 5)
然后,有一个约定,大多数(不是所有)处理字符串的C函数,都希望最后一个字符是\0
(知道它的结尾)。其他一些(请参见strncpy
)需要将长度作为额外参数,并且可以添加或不添加“\0”。因此,如果我添加char somestring=“somestring”
,这有效吗?@Holland,因为您正在为字符分配指针。或者,更准确地说,它是有效的(在C语言中,在C++中不要这样认为),但不会达到您期望的效果。但是,char*somestring=“somestring”
可以。char somestring=“somestring”怎么样
在C语言中有效?如果不从编译器获得(合法的)警告,你就不能将指针分配到字符,对吗?嗯……我想这只是一个警告(GCC说警告:初始化从指针生成整数而不进行强制转换),而不是一个错误,因此它是“允许的”。但只有在抗议的情况下。(作为局部变量初始值设定项,它只会引发该警告;作为全局变量,我还得到错误:初始值设定项元素在加载时不可计算,这表明它并不总是有效。)@Jonathan,只要标准允许,它是有效的。标准还允许I=I++--I;
(无论它有多未定义)但这并不是一个好主意:-)关于全局(或任何静态存储持续时间,例如在本地前面加上static
),您是对的,因为字符串的地址在编译时是未知的(这将在链接或加载时完成)。作为一个局部变量,它是在函数运行时计算的。您可能会看到一个很好的教程,关于数组衰减的部分将帮助您回答这个问题。另外请注意char*x=“…”;
支持向后兼容,但由于修改x
指向的数组是非法的,因此应编写const char*x=“…”;
。在我所知的任何语言中,字符串都是字符数组。
int * i = &someint;
#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;
}
char *str = "something";
char *str = {'s', 'o', 'm', 'e', 't', 'h', 'i', 'n', 'g', '\0'};
^ ^^^^^
|
+- str
str[5]
*(str + 5)