首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C語言函數返回指針陷阱:二維數組參數與指針運算錯誤分析

     編輯:程式設計綜合問答

問題描述

編寫一個函數 search,遍歷二維數組 score[4][3],若某行中有任一分數低於閾值 line,則返回該行首地址並在主函數中輸出該行三個分數。但程序運行結果不符預期。

原始代碼

#include <stdio.h>

float *search(float *(pointer)[3], float line); // 聲明與定義不匹配

int main() {
    float score[][3] = { {23,56,89}, {56,12,91}, {81,73,80}, {34,62,95} };
    float line_num;
    int i;
    float *p_addr;
    printf("input the limit line:\n");
    scanf("%f", &line_num);
    p_addr = search(score, line_num);
    printf("the student's scores are listed here:\n");
    for(i=0; i<3; i++) printf("%f\t", *(p_addr+i));
    putchar('\n');
    return 0;
}

float *search(float *(pointer)[4], float line) { // 參數類型錯誤
    float *p_addr;
    int i, j;
    for(i=0; i<4; i++) {
        for(j=0; j<3; j++) {
            if(*(*(pointer+i)+j) < line)
                return p_addr = *(pointer+i);
        }
    }
}

錯誤分析

  1. 函數聲明與定義參數類型不一致:聲明為 float *(pointer)[3],定義為 float *(pointer)[4],且二維數組退化為指針時應為 float (*pointer)[3](指向包含3個float的數組的指針),而非指針數組。
  2. 未處理未找到情況:若所有分數均達標,函數無返回值,導致未定義行為。
  3. 指針運算混淆:*(pointer+i) 取得第 i 行首地址,但參數類型錯誤導致偏移計算錯誤。

修正代碼

#include <stdio.h>
#include <stdlib.h>

float *search(float pointer[][3], float line); // 正確聲明:pointer 是指向 float[3] 的指針

int main() {
    float score[][3] = { {23,56,89}, {56,12,91}, {81,73,80}, {34,62,95} };
    float line_num;
    int i;
    float *p_addr = NULL;
    printf("input the limit line:\n");
    scanf("%f", &line_num);
    p_addr = search(score, line_num);
    if (p_addr) {
        printf("the student's scores are listed here:\n");
        for(i=0; i<3; i++) printf("%f\t", *(p_addr+i));
        putchar('\n');
    } else {
        printf("No student has score below %.2f\n", line_num);
    }
    return 0;
}

float *search(float pointer[][3], float line) {
    int i, j;
    for(i=0; i<4; i++) {
        for(j=0; j<3; j++) {
            if(pointer[i][j] < line) // 直接使用下標訪問,清晰不易出錯
                return pointer[i]; // 返回第 i 行首地址
        }
    }
    return NULL; // 明確表示未找到
}

關鍵點總結

  • 二維數組作為函數參數時,聲明為 type (*ptr)[cols] 或 type ptr[][cols],第一維可省略,第二維必須給出。
  • 函數需覆蓋所有控制路徑返回值,避免未定義行為。
  • 優先使用下標 pointer[i][j] 而非複雜指針解引用,提高可讀性並減少錯誤。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved