C语言 函数数组中的最后一个数字

rur96b6h  于 2023-01-04  发布在  其他
关注(0)|答案(6)|浏览(292)

我想写一个函数,有一个给定的数组和一个数字N,这个数字最后一次出现时,我想返回address,如果找不到这个数字,我想使用一个NULL指针
我编写的代码的开头是:

int main(void) {

    int n = 3;

    int ary[6] = { 1,3,7,8,3,9 };

    for (int i = 0; i <= 6; i++) {
        if (ary[i] == 3) {
            printf("%u\n", ary[i]);
        }
        
    }

    return 0;
}

命令提示符中的结果:

3
3

我最大的麻烦是:
1.它将打印所有匹配项,但不是最后一个匹配项
1.我不太使用指针,所以不知道如何使用NULL指针

lmyy7pcs

lmyy7pcs1#

我发现你的程序有很多小问题:
1.如果你想创建一个函数,那么创建一个函数时,你的参数和返回类型是显式的,而不是直接在main中编码。

  1. C数组,像大多数语言一样,从0开始索引,所以如果有N个元素,第一个元素的索引是0,那么第二个元素的索引是1,等等......所以最后一个元素(第N个)的索引是N-1,所以在你的for循环中,总是有条件“i〈size”,而不是“i〈= size”或(“i〈= size-1”,如果你是个怪人)
    1.如果你只想对某件事的最后一次发生采取行动,不要对每一次都采取行动,只要把每一次新的发生都保存到同一个变量中,然后,当你确定它是最后一次发生时,就对它采取行动。
    您描述的函数的最终版本为:
int* lastOccurence(int n, int* arr, int size){
    int* pos = NULL;
    
    for(int i = 0; i < size; i++){
        if(arr[i] == n){
            pos = &arr[i]; //Should be equal to arr + i*sizeof(int)
        }
    }

    return pos;
}

int main(void){
    int n = 3;

    int ary[6] = { 1,3,7,8,3,9 };

    printf("%p\n", lastOccurence(3, ary, 6);

    return 0;
}

然后我会添加NULL指针就是0,我的意思是在运行时头文件中有一行“#define NULL 0”,这只是一个约定,内存地址0不存在,为了清晰起见我们使用NULL代替0,但这是完全一样的。

bnl4lu3b

bnl4lu3b2#

漏洞:

  • i <= 6访问数组超出界限,请更改为i < 6
  • printf("%u\n", ary[i]);打印值,而不是索引。
  • 您实际上并不是将该值与n进行比较,而是与硬编码的3进行比较。

我 * 认为 * 你正在寻找这样的东西:

#include <stdio.h>

int main(void) 
{
  int n = 3;

  int ary[6] = { 1,3,7,8,3,9 };
  int* last_index = NULL;

  for (int i = 0; i < 6; i++) {
    if (ary[i] == n) {
      last_index = &ary[i];
    }
  }

  if(last_index == NULL) {
    printf("Number not found\n");
  }
  else {
    printf("Last index: %d\n", (int)(last_index - ary));
  }

  return 0;
}

指针last_index指向最后找到的项,如果有的话,通过减去数组的基地址last_index - ary,我们进行指针运算,得到数组项。
强制转换为int是必要的,以避免在C中减去指针实际上会得到一个名为ptrdiff_t的大整数类型的结果-初学者不需要担心这个问题,所以只需强制转换即可。

7nbnzgx9

7nbnzgx93#

首先,您将从数组范围外读取,因为您的数组最后一个元素是5,而您读取的最多为6,这可能会导致分段错误。

for (int i = 0; i <= 6; i++)  // reads from 0 to 6 range! It is roughly equal to for (int i = 0; i == 6; i++)

致:

for (int i = 0; i < 6; i++)  // reads from 0 to 5

此号码最后一次出现时,我希望返回为地址。
您只打印值3,不打印地址。为此,您需要使用&运算符。
如果找不到所述数字,我想使用NULL指针
我不明白,你想在哪里返回nullpointer?主函数不能返回nullpointer,这与它的定义相矛盾。要这样做,你需要把它放在单独的函数中,然后返回NULL
如果你想返回最后一次出现的结果,那么我将从这个数组的末尾开始迭代:

for (int i = 5; i > -1; i--) {
    if (ary[i] == 3) {
        printf("place in array: %u\n", i); // to print iterator
        printf("place in memory: %p\n", &(ary[i])); // to print pointer
        break;  // if you want to print only last occurence in array and don't read ruther
    }
    else if (i == 0) {
        printf("None occurences found");
    }
}
yzuktlbb

yzuktlbb4#

1.如果你想 * 返回一个地址 *,你需要使用一个函数,而不是用main写代码
1.当你想要返回最后一个出现的地址时,你应该从最后一个元素向第一个元素迭代数组,而不是从第一个元素向最后一个元素迭代。
下面是这种功能的两种不同实现。

#include <stdio.h>
#include <assert.h>

int* f(int n, size_t sz, int a[])
{
    assert(sz > 0 && a != NULL);

    // Iterate the array from last element towards first element
    int* p = a + sz;
    do
    {
        --p;
        if (*p == n) return p;
    } while(p != a);
    
    return NULL;
}

int* g(int n, size_t sz, int a[])
{
    assert(sz > 0 && a != NULL);

    // Iterate the array from last element towards first element
    size_t i = sz;
    do
    {
        --i;
        if (a[i] == n) return &a[i];
    } while (i > 0);
    
    return NULL;
}

int main(void) 
{
    int n = 3;
    int ary[] = { 1,3,7,8,3,9 };
    size_t elements = sizeof ary / sizeof ary[0]; 
    int* p;

    p = g(n, elements, ary);  // or p = f(n, elements, ary);
    if (p != NULL)
    {
        printf("Found at address %p - value %d\n", (void*)p, *p);
    }
    else
    {
        printf("Not found. The function returned %p\n", (void*)p);
    }

    return 0;
}
guz6ccqo

guz6ccqo5#

处理问题中的 * 指定要求 *(例如,一个 * 函数 * 搜索数字并返回其最后一次出现的地址,或NULL),下面的代码提供了一种满足这些要求的方法。

#include <stdio.h>

// Note that an array, passed as an argument, is converted to a pointer (to the
// first element). We can change this in our function, because that pointer is
// passed BY VALUE (i.e. it's a copy), so it won't change the original
int* FindLast(int* arr, size_t length, int find)
{
    int* answer = NULL; // The result pointer: set to NULL to start off with
    for (size_t i = 0; i < length; ++i) { // Note the use of < rather than <=
        if (*arr == find) { 
            answer = arr; // Found, so set our pointer to the ADDRESS of this element
            // Note that, if multiple occurrences exist, the LAST one will be the answer
        }
        ++arr; // Move on to the next element's address
    }
    return answer;
}

int main(void)
{
    int num = 3; // Number to find
    int ary[6] = { 1,3,7,8,3,9 }; // array to search
    size_t arrlen = sizeof(ary) / sizeof(ary[0]); // Classic way to get length of an array

    int* result = FindLast(ary, arrlen, num); // Call the function!

    if (result == NULL) { // No match was found ...
        printf("No match was found in the array!\n");
    }
    else {
        printf("The address of the last match found is %p.\n", (void*)result); // Show the address
        printf("The element at that address is: %d\n", *result); // Just for a verification/check!
    }

    return 0;
}
nmpmafwu

nmpmafwu6#

到目前为止有很多答案,而且都是非常好的答案,所以我不会重复关于数组边界等的相同评论。
然而,我将采取不同的方法,并声明,“我想使用一个空指针”是这个任务的一个愚蠢的先决条件,它只会把一个非常简单的问题弄得混乱和复杂化。“我想使用......”是切掉你的鼻子来怨恨你的脸。
KISS的原则是“保持简单,圣......!!”那些将要阅读/修改你的代码的人会欣赏你的努力,而不是钦佩你做出了错误的决定,使他们的日子更糟。
数组很容易在索引到达每个元素方面进行构思。如果你想训练指针和空指针的使用,我建议你探索“链表”和/或“二叉树”。那些数据结构是建立在指针的实用性之上的。

int main( void ) {
    const int n = 3, ary[] = { 1, 3, 7, 8, 3, 9 };
    size_t sz = sizeof ary/sizeof ary[0];

    // search for the LAST match by starting at the end, not the beginning.
    while(  sz-- )
        if( ary[ sz ] == n ) {
            printf( "ary[ %sz ] = %d\n", sz, n );
            return 0;
        }
    puts( "not found" );

    return 1; // failed to find it.
}

考虑到要搜索的数组有很多兆字节。要找到最后一个匹配项,从数组的尾部而不是头部开始是有意义的。简单...

相关问题