为什么指针可以自由地用作数组?我认为指针在内存操作中更强大和重要吗?有人可以向我解释指针在哪种情况下更重要吗?
这是我的代码:
char * myString ="This is my String";
while(*myString){
putchar(*myString++);
}
puts("\n");
char * myString1 ="This is my String";
int j=0;
while(myString1[j]!='\0'){
putchar(myString1[j++]);
}
他们打印相同的结果。
答案 0 :(得分:6)
为什么指针可以自由地用作数组?
除非它是sizeof
或一元&
(地址)运算符的操作数,否则数组表达式将转换为指针表达式...
我认为指针在内存操作中更强大,更重要吗?有人可以向我解释指针在哪种情况下变得更重要吗?
数组与指针有不同的用例;他们是相关的,但不能互相替代。两者都不比另一个更重要。
例如,正如Mohamed Fouad中提到的answer一样,数组是一组连续的元素。我们不能用指针存储一组元素,除非指针指向一个数组。
作为另一个例子,可以使用其中任何一个但指针通常更合适,请考虑fscanf
的工作原理。当您想要将一系列十进制数字字符作为int
读取时,您可以编写类似int destination; fscanf(source_file, "%d\n", &destination);
的内容。 &
(address-of)操作生成指向destination
的指针,指针允许fscanf
以destination
可见的方式写入fscanf
回报。
您也可以将其写为int destination[1]; fscanf(source_file, "%d\n", destination);
,但稍后您将指代destination[0]
,可能是多次,而不是destination
......您应该保持关注打开以避免代码中不必要的混乱,因此前一种方法(int destination; ...
)已经成为scanf
(而不是基于数组的版本)的习惯用法,因为它更清晰。
还有更多示例指针甚至没有指向对象,因此无法以数组的形式存储。例如,让我们考虑bsearch
。 bsearch
返回void *
,并在其参数中使用void *
,并与函数指针一起使用。这些都不被认为是指向特定类型的对象,实际上前者可以指向任何类型对象或根本没有对象。因此,当bsearch
无法在数组中找到某个项时,它会返回NULL
(指向 nothing 的指针),这是一个无法正确替换数组的用例。 / p>
函数不是对象或值,不能存储在数组中,因此数组与函数指针没有相似的类比。
他们打印相同的结果。
也许你打算写char myString1[] = "This is my String";
。这就是我们声明数组的方式。你写的是,char * myString1 ...
表示一个指针声明。
myString1
和myString1[j]
中的表达式myString1[j++]
从数组表达式转换为指针表达式。这有意义吗?
array[subscript]
运算符实际上是pointer[subscript]
运算符。这相当于*(array + subscript)
,但请回想一下array
表达式变为pointer expression
,因此编写*(pointer + subscript)
可能更有意义。
为了增加上面提到的函数指针,function(call)
运算符实际上是一个pointer(call)
运算,它与pointer[subscribt]
运算方式有惊人的相似之处隐式转换发生。尽管如此,它是可以观察到的:
typedef int main_func(void); // declare a new type named main_func to point at
int main(void) {
int x[1];
int *y = x; // notice lack of ampersand, array-to-pointer conversion happens implicitly
main_func *m = main; // notice lack of ampersand, function-to-pointer conversion happens implicitly
return (*m)(); // main calls itself via pointer m (don't do this)
}
您可能会注意到等价,现在:在第一个示例中,您重复递增指针变量,而在第二个示例中,您反复递增下标。除此之外,这些操作几乎完全相同。
如果您正在使用任何现代优化编译器进行编译(使用-O3
),那么二进制文件之间应该没有任何区别。尽量避免过早优化;它通常是非建设性的。编写清晰的代码,然后使用您的分析器确定最重要的瓶颈在哪里。
答案 1 :(得分:1)
让我们了解在c ++中调用函数并向其传递参数时会发生什么 它将孔对象(或数组)复制到内存中的新位置,然后开始执行该功能 1-如果这个对象的大小很大,这将是一个大问题(浪费时间和内存) 要么 2-如果我们想要这个函数来编辑原始对象而不是它的副本 指针是解决方案 要么 3-如果我们有一个应该响应非常快的系统(如现代汽车中的摄像系统),如果我们编写像
这样的代码object x = new object;
没有重载新操作符这将非常慢 重载new运算符将增强此过程,因为将把我们的新对象放在不需要的地方
数组是内存中的连续空间 如果我们有起始的adddres,我们可以加上对象的大小来到达下一个 减去你在代码中写的内容的对象
指针在内存操作中更强大和重要,这是完全真实的陈述 here您会找到更多答案
抱歉英语不好:D
答案 2 :(得分:1)
C中的指针只是内存中的一个位置。它指向内存中的单个位置。任何东西都可以存储在那里:int,char,字符串(char数组),甚至是更复杂的对象,比如struct。
指针比数组更“强大”,因为它们可以“指向”任何东西。这是因为它们只是指向可以存储任何内容的内存地址。
指针的内存地址是存储在那里的内容的开头。因此,项目的长度取决于项目所需的字节数。因此对于int,内存地址可以是0x0044
,而int
将占用sizeof(int)
个字节。如果你有一个存储在该内存地址的结构会发生同样的事情,它会占用sizeof(nameOfStruct)
个字节数。
基本上,当您使用指针初始化字符数组或字符串时,您在内存地址分配足够的字节来存储字符串的长度。
这意味着你声明一个指向角色的指针。 myString
和myString1
都是指向char
的指针。然后,当您为指针分配一串文本时,您要求程序找到足够的内存来存储该字符串。程序将"This is my String"
连续存储在内存中,并将内存地址分配给指针myString
的第一个字符。所以现在myString
'指向'内存中字符串的开头。
运行以下代码时最终会做什么
char * myString1 ="This is my String";
int j=0;
while(myString1[j]!='\0'){
putchar(myString1[j++]);
}
您是否正在查找字符串以查找空终止符或字符串的结尾。基本上,每次j
前进一个,你的一个字符在内存中向前移动,并打印出那里的内容,直到你到达空终止符或字符串的结尾。当然使用c,如果你超过字符串的末尾,程序就不会关心了,并且只会继续输出内存中沿线的下一个垃圾。这是因为当你推进j
时,你只是前进到下一个内存地址并打印出那些内容。