【问题标题】:How to efficiently use 2D pointers instead of 2D arrays?如何有效地使用二维指针而不是二维数组?
【发布时间】:2016-04-20 03:07:37
【问题描述】:

我需要为这段代码使用指针。没有数组,没有结构。例如,如果我需要一个浮点数组来保存分数,请不要使用浮点分数 [15]。而是使用 float *score,然后使用动态内存分配来保存所需的内存。我必须以最佳方式使用内存,也就是说,如果您只有 6 个分数,我需要使用它来指向 sizeof(float)*6 字节的内存块。同样,要保存名称,而不是使用 2D char 数组,使用 2D 指针 (char firstName[15][20] → char **firstName)。

我有下面的 C 代码,我需要使用 2d 指针的帮助。代码编译并运行,但是在我输入名称后,如果崩溃并且在处理它这么长时间后我被卡住了。

提前谢谢你


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

void Option_Scren();

void print_records(int size, char **firstname, char **lastname, float *score);
void search_by_firstname(int size, char **firstname, char **lastname, float *score);
void search_by_lastname(int size, char **firstname, char **lastname, float *score);
void sort_by_score(int size, char **firstname, char **lastname, float *score);
void sort_by_lastname(int size, char **firstname, char **lastname, float *score);


int main(void)
{
    char **First_Name;
    char **Last_Name;
    float *Score_;
    int n = 0;
    int i = 0;
    int x = -1;

    First_Name = (char **)malloc(sizeof(char *));
    Last_Name = (char **)malloc(sizeof(char *));
    Score_ = (float *)malloc(sizeof(int)*15);
    for(i=0; i<15; i++)
    {
        First_Name[i] = (char *)malloc(20*sizeof(char));
        Last_Name[i] = (char *)malloc(20*sizeof(char));
    }

    //char *nametofind = (char *)malloc(20*sizeof(char));

    printf("Please indicate the number of records you want to enter (min 5, max 15):\n");
    scanf("%d", &n);
    printf("Please input records of students (enter a new line after each record), with the following format \nFirstname Lastname Score\n");
    for (i = 0; i<n; i++)
    {
        scanf("%s %s %f", &First_Name[i][0], &Last_Name[i][0], &Score_[i]);
    }
    do
    {
        printf("\n---you may access the records by---\n");
        printf("Print records (press 1)\n");
        printf("Search by first name (press 2)\n");
        printf("Search by last name (press 3)\n");
        printf("Sort by score (press 4)\n");
        printf("Sort by last name (press 5)\n");
        printf("Exit program (press 0)\n");
        printf("--------------------------\n\n");
        printf("Please a function by entering a value from 0 to 5.\n");
        scanf("%d", &x);
        printf("You have selected option: %d\n", x);
        switch (x)
        {
        case 1:
            print_records(n, First_Name, Last_Name, Score_);
            break;
        case 2:
            search_by_firstname(n, First_Name, Last_Name, Score_);
            break;
        case 3:
            search_by_lastname(n, First_Name, Last_Name, Score_);
            break;
        case 4:
            sort_by_score(n, First_Name, Last_Name, Score_);
            break;
        case 5:
            sort_by_lastname(n, First_Name, Last_Name, Score_);
            break;
        default: printf("Please only enter a number from 0 to 5\n");
        }
    }
    while (x != 0);
    printf("Thank You \nGood Bye\n");
    return 0;
}

void print_records(int size, char **firstname, char **lastname, float *score)
{
    int i = 0;
    for (i = 0; i < size; i++)
    {
        printf("First Name: %s, Last Name: %s, Score: %.2f\n", firstname[i], lastname[i], score[i]);
    }
}

void search_by_firstname(int size, char **firstname, char **lastname, float *score)
{
    int i = 0;
    char *Name_Search = (char *)malloc(20*sizeof(char));
    printf("Please enter the first name of student record you wish to print: ");

    fgets(Name_Search, 20, stdin);
    for (i = 0; i<size; i++)
    {
        if (strcmp(Name_Search, firstname[i]) == 0)
        {
            printf("First Name: %s, Last Name: %s, Score: %.2f\n", firstname[i], lastname[i], score[i]);
        }
    }
}

void search_by_lastname(int size, char **firstname, char **lastname, float *score)
{
    int i = 0;
    char *Name_Search = (char *)malloc(20*sizeof(char));
    printf("Please enter last name of student record you wish to print: ");

    fgets(Name_Search, 20, stdin);
    for (i = 0; i<size; i++)
    {
        if (strcmp(Name_Search, lastname[i]) == 0)
        {
            printf("First Name: %s, Last Name: %s, Score: %.2f\n", firstname[i], lastname[i], score[i]);
        }
    }
}

void sort_by_score(int size, char **firstname, char **lastname, float *score)
{
    int i = 0;
    int j = 0;
    float tempscore;
    char tempfirstname[20];
    char templastname[20];
    // bubble sort
    for (i = 0; i<size - 1; i++)
    {
        for (j = 0; j<size - i - 1; j++)
        {
            if (score[j]>score[j + 1])
            {
                tempscore = score[j];
                score[j] = score[j + 1];
                score[j + 1] = tempscore;
                strcpy(tempfirstname, firstname[j]);
                strcpy(firstname[j], firstname[j + 1]);
                strcpy(firstname[j + 1], tempfirstname);
                strcpy(templastname, lastname[j]);
                strcpy(lastname[j], lastname[j + 1]);
                strcpy(lastname[j + 1], templastname);
            }
        }
    }
    print_records(size, firstname, lastname, score);
}

void sort_by_lastname(int size, char **firstname, char **lastname, float *score)
{
    int i = 0;
    int j = 0;
    float tempscore;
    char tempfirstname[20];
    char templastname[20];
    // bubble sort
    for (i = 0; i<size - 1; i++)
    {
        for (j = 0; j<size - i - 1; j++)
        {
            if (strcmp(lastname[j], lastname[j + 1])>0)
            {
                strcpy(tempfirstname, firstname[j]);
                strcpy(firstname[j], firstname[j + 1]);
                strcpy(firstname[j + 1], tempfirstname);
                strcpy(templastname, lastname[j]);
                strcpy(lastname[j], lastname[j + 1]);
                strcpy(lastname[j + 1], templastname);
                tempscore = score[j];
                score[j] = score[j + 1];
                score[j + 1] = tempscore;
            }
        }
    }
    print_records(size, firstname, lastname, score);
}

【问题讨论】:

  • 你试过自己调试吗?你能给出一个错误的输出吗?
  • 在分配内存之前,需要询问用户他们想要多少条记录。
  • 我尝试在调用记录之前移动它,但它仍然崩溃。
  • 一些小问题 - 你应该添加一个case 0: break;。否则你会下拉到default: 并错误地打印错误信息
  • 这些限制是针对真实代码的还是仅仅是一个分配?如果是后者,你的导师真的很糟糕。我不明白为什么还要在课堂上教授伪数组。

标签: c arrays string pointers 2d


【解决方案1】:

基本上你正在做的是对一些数据使用动态分配的存储,你分配的方式有一些问题,见下文。另外,不要转换malloc的返回值,void*与标准C中的其他指针兼容。其次,你不需要做sizeof(char),它在标准中定义为1

// suppose the number of elements you want to store if 15
#define N 15
char **First_Name;
char **Last_Name;
float *Score_;

// First_Name = (char **)malloc(sizeof(char *));
// you are allocating an buffer to hold ONE char* here, use following instead
First_Name = malloc(N * sizeof(char*));

// Last_Name = (char **)malloc(sizeof(char *));
// same issue here, should be:
Last_Name = malloc(N * sizeof(char*));

// Score_ = (float *)malloc(sizeof(int)*15);
// Score_ is an pointer of floats, so you cannot use sizeof(int) to calculate the size
Score_ = malloc(N * sizeof(float));

for(i=0; i<N; i++) {
     First_Name[i] = malloc(20);
     Last_Name[i] = malloc(20);
}

【讨论】:

  • 可能想注释掉或删除Score_ = (float *)malloc(sizeof(int)*15);这一行
  • 我想你也想要Last_Name = malloc(N * sizeof(char*));
猜你喜欢
  • 2021-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-09
  • 2017-04-26
相关资源
最近更新 更多