c - 我的代码中有错误?(使用函数和指针对数组进行排序)

标签 c pointers

有两个程序都工作正常,你能解释一下为什么吗?

//sorting of array using pointers
#define n 5
void sort(int m,int *x);
main()
{
    int i,a[n];

    printf("enter the values");
    for(i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
    }
    sort(n,a);//not sending the address but still my code works only when I define array but when i use int data type then I need to pass address , why is this so?
}
void sort(int m,int *x)
{
    int i,j,temp,k;
    for(i=1;i<=m-1;i++)
    {
        for(j=1;j<=m-1;j++)//this lop is to sort array
        {
            if(*(x+j-1)>=*(x+j))
            {
                temp=*(x+j-1);
                *(x+j-1)=*(x+j);
                *(x+j)=temp;
            }
        }
    }
    for(k=0;k<m;k++)
    {
        printf("\n%d\n",*(x));
        x++;//when i am not using *x++
    }
}

当我使用这个程序时,我的程序没有改变或没有给出错误

//sorting of arrays sing pointers
    #define n 5
    void sort(int m,int *x);
    main()
    {
        int i,a[n];

        printf("enter the values");
        for(i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
        }
        sort(n,&a);//and '&a' instead of 'a'
    }
    void sort(int m,int *x)
    {
        int i,j,temp,k;
        for(i=1;i<=m-1;i++)
        {
            for(j=1;j<=m-1;j++)//this loop is to sort array
            {
                if(*(x+j-1)>=*(x+j))
                {
                    temp=*(x+j-1);
                    *(x+j-1)=*(x+j);
                    *(x+j)=temp;
                }
            }
        }
        for(k=0;k<m;k++)
        {
            printf("\n%d\n",*(x));
            *x++;//here i have used *x++ instead of x++
        }
    }

为什么当我们定义int数据类型时需要在函数调用中传递地址,而当我们使用指针时,在调用函数时不需要在数组中传递地址? 请消除我的疑问。

最佳答案

您的编译结果肯定应该发生变化。

通过&a到一个期望 int * 的函数至少应该标记一个编译器警告,并且对于任何合理的当前标准兼容编译器,一个彻底的错误。类型int *int(*)[5]不是同义词。我不知道你正在使用什么工具链,但当前的任何工具都应该令人作呕。例如,使用 std=c11 clang 3.5 给出:

Incompatible pointer types passing 'int (*)[5]' to parameter of type 'int *'

无论如何,表达式中使用的数组(如您的数组)会转换为类型指针(在您的情况下,类型为 int ),其值是序列中第一个元素的地址。将其作为参数传递给函数会产生这样的表达式,从而转换为指向 int 的临时指针。 .

因此,

foo(int *x);

int main()
{
    int ar[5];
    foo(ar);
}

结果为x持有地址ar的第一个元素。数组的第一个元素也必须位于数组本身的地址,因此严格来说,地址由 ar 表示。和&ar相同的地址。但这些表达式的指针转换结果的类型不同。在前一种情况下,指针类型为 int * ;指向 int 的指针。对于后者,类型为 int (*)[5] ;指向 array-of-5- ​​int 的指针。如果您认为这没有什么区别,那么它肯定可以,特别是对于指针算术:

#include <stdio.h>

#define n 5

int main()
{
    int ar[n];

    printf("ar    = %p\n", ar);
    printf("ar+1  = %p\n", ar+1);
    printf("&ar   = %p\n", &ar);
    printf("&ar+1 = %p\n", &ar+1);

    return 0;
}

输出(您的输出会有所不同,但差异应该相似)

ar    = 0x7fff5fbffa20
ar+1  = 0x7fff5fbffa24
&ar   = 0x7fff5fbffa20
&ar+1 = 0x7fff5fbffa34

注意 ar 是如何做到的和&ar反射(reflect)相同的地址,但添加 1 的指针运算应用时表现出显着差异。这种差异是由于这些指针的类型不同造成的。在第一个中,它的大小为 int 。在第二个中,它的大小增加了 int[5] 的大小。

<子> 向希望所有这些地址都转换为 void* 的纯粹主义者致歉。 。抱歉,来晚了。

<小时/>

关于x++*x++ ,即operator precedence在上类。后缀运算符++优先级高于间接 * 。结果是单独的表达式 *x++;是有效的,例如:

  1. 取指针的值x ,将其存储在一个看不见的临时位置。
  2. 增加 x 中的地址.
  3. 应用间接运算符 *到在 (1) 期间保存到 temp 的地址。这相当于 *x增量之前。

由于您对所得估值不采取任何措施,(3) 变得无关紧要,*x++;相当于 x++;最终行为: x 中保存的地址的增量相当于一种类型宽度 ( int )。

关于c - 我的代码中有错误?(使用函数和指针对数组进行排序),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29069891/

相关文章:

c - 如何使用代码中已定义的变量为变量设置值?

c - 简单的 C 指针问题

带参数的回调

c - 我不明白指针、地址和范围

c - findAndReplace函数的实现

c++ - _itoa 和 itoa 有什么区别?

c - 恢复 C (gcc) 中的递归函数?

c - C中的*myptr++和*(myptr++)有什么区别

c++ - 为什么有两种通过指针调用函数的方式?

c - 字符指针数组打印垃圾