C中的指针与数组类似,但指针更有用

时间:2015-07-19 04:10:59

标签: c pointers

为什么指针可以自由地用作数组?我认为指针在内存操作中更强大和重要吗?有人可以向我解释指针在哪种情况下更重要吗?

这是我的代码:

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++]);
}

他们打印相同的结果。

3 个答案:

答案 0 :(得分:6)

  

为什么指针可以自由地用作数组?

除非它是sizeof或一元&(地址)运算符的操作数,否则数组表达式将转换为指针表达式...

  

我认为指针在内存操作中更强大,更重要吗?有人可以向我解释指针在哪种情况下变得更重要吗?

数组与指针有不同的用例;他们是相关的,但不能互相替代。两者都不比另一个更重要。

例如,正如Mohamed Fouad中提到的answer一样,数组是一组连续的元素。我们不能用指针存储一组元素,除非指针指向一个数组。

作为另一个例子,可以使用其中任何一个但指针通常更合适,请考虑fscanf的工作原理。当您想要将一系列十进制数字字符作为int读取时,您可以编写类似int destination; fscanf(source_file, "%d\n", &destination);的内容。 &(address-of)操作生成指向destination的指针,指针允许fscanfdestination可见的方式写入fscanf回报。

您也可以将其写为int destination[1]; fscanf(source_file, "%d\n", destination);,但稍后您将指代destination[0],可能是多次,而不是destination ......您应该保持关注打开以避免代码中不必要的混乱,因此前一种方法(int destination; ...)已经成为scanf(而不是基于数组的版本)的习惯用法,因为它更清晰。

还有更多示例指针甚至没有指向对象,因此无法以数组的形式存储。例如,让我们考虑bsearchbsearch返回void *,并在其参数中使用void *,并与函数指针一起使用。这些都不被认为是指向特定类型的对象,实际上前者可以指向任何类型对象或根本没有对象。因此,当bsearch无法在数组中找到某个项时,它会返回NULL(指向 nothing 的指针),这是一个无法正确替换数组的用例。 / p>

函数不是对象或值,不能存储在数组中,因此数组与函数指针没有相似的类比。

  

他们打印相同的结果。

也许你打算写char myString1[] = "This is my String";。这就是我们声明数组的方式。你写的是,char * myString1 ...表示一个指针声明。

myString1myString1[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)个字节数。

基本上,当您使用指针初始化字符数组或字符串时,您在内存地址分配足够的字节来存储字符串的长度。

这意味着你声明一个指向角色的指针。 myStringmyString1都是指向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时,你只是前进到下一个内存地址并打印出那些内容。