首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在普通C中使用指针变量打印数组

如何在普通C中使用指针变量打印数组
EN

Stack Overflow用户
提问于 2022-02-14 16:35:29
回答 3查看 186关注 0票数 0

我正在对返回数组的函数进行一些测试,通过一些读取,我附带了以下内容:

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>

int i;

char * askData() {
    static char data[5];
    for(i = 0; i < 5; i++)
        scanf("%s", &data[i]);

    return data;
}

int main() {
    char* data = askData();
    
    printf("Flag 1\n");
    for(i = 0; i < 5; i++)
        printf("Loop %i: %s\n", i, &data[i]);

    printf("Flag 2\n");
}

我想要做的是分别从指针中打印每个元素(非常像数组,但我没有使用它,因为C函数单独不能返回数组)。

输入:

代码语言:javascript
复制
Harry
Hermione
Ronald
Draco
Voldemort

预期产出:

代码语言:javascript
复制
Flag 1
Loop 0: Harry
Loop 1: Hermione
Loop 2: Ronald
Loop 3: Draco
Loop 4: Voldemort
Flag 2

当前产出:

代码语言:javascript
复制
Flag 1
Loop 0: HHRDVoldemort
Loop 1: HRDVoldemort
Loop 2: RDVoldemort
Loop 3: DVoldemort
Loop 4: Voldemort
Flag 2
EN

回答 3

Stack Overflow用户

发布于 2022-02-14 16:45:12

printf("Loop %i: %s\n", i, %data[i]);

您正在打印一个字符,这就是为什么%c是必需的,而不需要打印%。

代码语言:javascript
复制
printf("Loop %i: %c\n", i, data[i]);
代码语言:javascript
复制
 #include <stdio.h>
   #include <stdlib.h>
   
   char * askData() {
       static char data[5];
       for(i = 0; i < 5; i++)
           scanf("%s", &data[i]);
   
       return data;
   }
   
   int main() {
       char* data = askData();
       int i; //its better here

       printf("Flag 1\n");
       for(i = 0; i < 5; i++)
           printf("Loop %i: %c\n", i, data[i]);
   
       printf("Flag 2\n");
   }
票数 1
EN

Stack Overflow用户

发布于 2022-02-14 17:13:02

data是一个char的数组,只能容纳一个4char长的字符串。循环遍历每个试图在其中存储字符串的char of data是不正确的。您应该去掉askData中的循环,而是在循环中调用该函数,类似于下面的内容。

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>

#define NUM_NAMES 5

// no point in making i global

char * askData() {
    // 5 chars can only hold a string of 4, not big enough for the names
    // you indicated. Memory is cheap, use some
    static char data[256];
    // limit scanf to read one less than the size of data, so as not to overflow
    scanf("%255s", data);

    return data;
}

int main(void) {
    printf("Flag 1\n");
    // better practice to use size_t types when working with sizes
    for(size_t i = 0; i < NUM_NAMES; i++){
        // call askData in a loop. Each call will overwrite the data there from the previous call
        char* data = askData();
        // %zu is the correct format specifier for printing size_t type
        printf("Loop %zu: %s\n", i, data);
    }

    printf("Flag 2\n");
}

注意,如果您想保存每个输入而不是覆盖,您将需要一个2D数组,类似于data[NUM_NAMES][256];,那么您可以调用askData一次并在该函数中恢复循环,或者继续在循环中调用askData并作为参数传递字符串索引。

游行示威

票数 1
EN

Stack Overflow用户

发布于 2022-02-14 17:24:06

所以你是对的,C不会像你所说的那样返回数组,但是我们在C中这样做的方式是将两种想法结合起来:

  1. 使用内存:通过分配内存区域,然后返回该内存区域的起始位置。 分配内存的函数调用称为malloc,然后必须使用free调用来释放该内存区域。
  2. 指针算法:我相信您已经知道C有一些基本类型(char、int、long、float、double和最近的bool);每个类型都需要不同的内存,所以C还提供了理解类型化指针的方便性(指针是标记内存位置的变量)。类型化指针可以理解它的关联类型有多大(以字节为单位),当在内部将其值增加1(C)时,它就会随着类型的大小而增加。

结合这些想法,我们可以得到数组:

因此,例如,如果您有一个由五个整数组成的数组,那么您将分配一个区域,即5 * sizeof(int);假设一个现代系统,sizeof(int)将是32位(或4个字节);所以您将得到一个20字节的内存区域,可以用这些值填充它。

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>

int * get_numbers(size_t count) {

     int *data = malloc(count * sizeof(int));
     if (!data) {
         return NULL; // could not allocate memory
     }

     // notice that we are increasing the index i by 1
     // data[i] shifts properly in memory by 4 bytes
     // to store the value of the next input.

     for(int i=0; i < count; i++) {
           scanf("%d", &data[i]);
     }
}

int main() {
     int *data = get_numbers(5);
     if (data == NULL) {
          fprintf(stderr, "Could not allocate memory\n");
          exit(-1);
     }

     for(int i = 0; i < 5; i++) {
         printf("data[%d] = %d\n", i, data[i]);
     }

     free(data); 
}

现在,在您的例子中,您有一些复杂的(但不是真正的),您希望能够在名称中读取,这些名称是“字符串”,在C中除了作为字符数组之外,这些字符串并不真正存在。

因此,要重新表述我们的问题是,需要一个名称数组。每个名称本身都是一个字符数组。问题是,C还可以理解类型指针(是指向指针的指针),并且可以计算出指针算法。

所以我们可以有一个充满不同类型的内存区域;类型指针本身可以在一个内存区域中有一个指针列表;然后确保该列表中的每个指针都指向一个有效的内存区域本身。

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>


char *get_one_name() {
    char *name = NULL;
    size_t len = 0;
    printf("Enter a name:");
    // getline takes a pointer, which if it's set to NULL
    // will perform a malloc internally that's big enough to
    // hold the input value.
    getline(&name, &len, stdin);
    return name;
}

char ** get_names(size_t count) {

    // this time we need memory region enough to hold
    // pointers to names
     char **data = malloc(count * sizeof(char *));
     if (!data) {
         return NULL; // could not allocate memory
     }

     for(int i=0; i < count; i++) {
         data[i] = get_one_name();
     }

     return data;
}

void free_names(char **data, size_t count) {
    for(int i = 0; i < count) {
        if(data[i] != NULL) {
            free(data[i]);
        }
    }
    free(data);
}

int main() {
     char **data = get_names(5);
     if (data == NULL) {
          fprintf(stderr, "Could not allocate memory\n");
          exit(-1);
     }

     for(int i = 0; i < 5; i++) {
         printf("data[%d] = %d\n", i, data[i]);
     }

     free_names(data, 5);
}

希望这能给你一些想法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71115196

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档