【问题标题】:Array in C and null characterC中的数组和空字符
【发布时间】:2020-01-04 03:58:52
【问题描述】:

我正在做一个由 Brian W. Kernighan 和 Dennis M. Ritchie 所著的“The C Programming Language”一书提出的关于数组的练习。 练习需要一个能够接收文本行作为输入并显示超过 80 个字符的程序。为方便起见,我在这里定义了最多 3 行输入,20 为最大长度,5 为显示的边框。

该程序运行良好,“printValues”函数让我可以查看哪些插入的行超过 5 个字符,但我的好奇心让我想看看是否确实将空字符 (/0) 放在了向量的未使用空间中。 令我惊讶的是,输出是多种多样的;如果我使用这样的输入:

one
two
helloworld

第一行的输出将是:

nomi[0][0]=o
nomi[0][1]=n
nomi[0][2]=e
nomi[0][3]=\0
nomi[0][4]=?
nomi[0][5]=
nomi[0][6]=\0
nomi[0][7]=\0
nomi[0][8]=\0
nomi[0][9]=?
nomi[0][10]=c
nomi[0][11]=
nomi[0][12]=
nomi[0][13]=\0
nomi[0][14]=\0
nomi[0][15]=\0
nomi[0][16]=
nomi[0][17]=\0
nomi[0][18]=\0
nomi[0][19]=\0

nomi[1][0]=t
nomi[1][1]=w
nomi[1][2]=o
nomi[1][3]=\0
nomi[1][4]=\0
nomi[1][5]=\0
nomi[1][6]=\0
nomi[1][7]=\0
nomi[1][8]=\0
nomi[1][9]=\0
nomi[1][10]=\0
nomi[1][11]=\0
nomi[1][12]=\0
nomi[1][13]=\0
nomi[1][14]=\0
nomi[1][15]=\0
nomi[1][16]=\0
nomi[1][17]=\0
nomi[1][18]=\0
nomi[1][19]=\0

nomi[2][0]=h
nomi[2][1]=e
nomi[2][2]=l
nomi[2][3]=l
nomi[2][4]=o
nomi[2][5]=w
nomi[2][6]=o
nomi[2][7]=r
nomi[2][8]=d
nomi[2][9]=\0
nomi[2][10]=\0
nomi[2][11]=\0
nomi[2][12]=\0
nomi[2][13]=\0
nomi[2][14]=\0
nomi[2][15]=\0
nomi[2][16]=\0
nomi[2][17]=\0
nomi[2][18]=\0
nomi[2][19]=\0

进行了一些测试,我意识到只有在第一行中,向量的空单元格中有一些奇怪的字符。 谁能给我解释一下?

对不起我的英语。

#include <stdio.h>
#define MAXNAMES 3
#define MAXNAMESLENGHT 20
#define HIGHERTHAN 5

void printValues(char names[][MAXNAMESLENGHT], char provisionalName[]);
void printIndexs(char names[][MAXNAMESLENGHT]);

int main() {
    char names[MAXNAMES][MAXNAMESLENGHT];   
    char provisionalName[MAXNAMESLENGHT];
    int i, e, c;

    for(i = 0; i <= MAXNAMES - 1; i++) {
        for(e = 0; e <= (MAXNAMESLENGHT - 2) && (c = getchar()) != EOF && c != '\n'; ++e) {
            names[i][e] = c;    
        }
        names[i][e] = '\0';
    }

    printValues(names, provisionalName);
    printIndexs(names);

    return 0;
}

void printValues(char names[][MAXNAMESLENGHT], char provisionalName[]) {
    printf("________________________________________");
    printf("\nI nomi che superano i %d caratteri sono:\n", HIGHERTHAN);

    int i, e;
    char flag = 'F';

    for(i = 0; i <= MAXNAMES - 1; ++i) {
        for(e = 0; e <= MAXNAMESLENGHT - 1 && names[i][e] != '\0'; ++e)
            provisionalName[e] = names[i][e];

        provisionalName[e] = '\0';
        if(e > HIGHERTHAN) {
            flag = 'T';
            printf("%s\n", provisionalName);
        }       
    }
    if(flag == 'F') printf("nessuno\n");
}

void printIndexs(char names[][MAXNAMESLENGHT]) {
    printf("________________________________________");
    printf("\nIndici:\n");

    for(int i = 0; i <= MAXNAMES - 1; ++i) {
        for(int e = 0; e <= MAXNAMESLENGHT - 1; ++e) {
            if(names[i][e] == '\n')                                 // return (\n)
                printf("names[%d][%d]=\\n\n", i, e);
            else if(names[i][e] == '\0')                            // null character (\0)
                printf("names[%d][%d]=\\0\n", i, e);
            else
                printf("names[%d][%d]=%c\n", i, e, names[i][e]);    // carattere
        }
        printf("\n");
    }       
    printf("\n");
}

【问题讨论】:

    标签: c arrays macos vector cc


    【解决方案1】:

    没有像static 这样的限定符在函数内部定义的对象不会自动初始化。 (您的数组是对象。)通常,编译器将 stack 用于此类对象(但除了简单地使用堆栈之外,它们可能使用处理器寄存器并进行各种优化)。您在该区域中看到的数据只是之前使用堆栈的剩余数据。 (虽然main 是你的C 程序中执行的第一个例程,但实际上在main 之前执行了启动代码,为你的程序设置C 环境。它在堆栈上留下了一些数据。)

    数组的元素永远不会是“空的”。对于char 对象,C 没有表示“空”的值。1 C 不会自动将您的数组初始化为“空”或在其元素中具有零值。当你定义数组时,你得到的只是保证有你可以访问的存储——你没有得到关于那个存储中有什么的任何保证。

    脚注

    1 C 的语义复杂,存在对象的值未指定的情况,这不仅意味着它的值不是由 C 的规则决定的,而且程序可能会认为对象没有固定值(每次使用时它可能看起来不同)。

    【讨论】:

    • 所以...memset.
    • @JL2210: 没有。在这个应用程序中不需要(K&R 中提出的问题); OP 只是好奇地检查了数组的其余部分。而且,如果有需要,可以使用= {0} 初始化数组。
    • 所以你是在告诉我,我不必担心我没用过的单元格里面有什么?在最后一个占用的单元格的末尾放置一个空字符就足够了,而不考虑下一步是什么?
    • @RobertoRocco:没有空元素。有些元素你没有使用。如果您不使用它们,它们中的内容无关紧要。
    • 事实上我在你回答我的时候纠正了我的问题!谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-12
    • 1970-01-01
    • 2013-10-22
    相关资源
    最近更新 更多