簡體   English   中英

為什么 memset 在功能上的工作方式不同?

[英]Why does memset work differently in functions?

我試圖弄清楚為什么當我從 function 內部調用 memset 時它不起作用。 當然,我可以使用 for 循環來重置所有值,但我是來學習的,這件事讓我沒有任何解釋。

/* First source code */
#include <stdio.h>
#include <string.h>

int main(void) {
    int i, j, num;

    printf("Digit a number :");
    scanf("%d", &num);

    int magic[num][num];

    printf("First\n");
    for(i = 0; i < num; ++i) {
        for(j = 0; j < num; ++j) {
            printf("%4d", magic[i][j]);
        }
        printf("\n\n");
    }

    memset(magic, 0, sizeof(magic));

    printf("Before\n");
    for(i = 0; i < num; ++i) {
        for(j = 0; j < num; ++j) {
            printf("%4d", magic[i][j]);
        }
        printf("\n\n");
    }

    return 0;
}

/* Second source code */
#include <stdio.h>
#include <string.h>

void create_magic_square(int n, int magic_square[][n]);
void print_magic_square(int n, int magic_square[][n]);

int main(void) {
    int num;
    printf("Digit a number :");
    scanf("%d", &num);
    int magic[num][num];
    create_magic_square(num, magic);
    return 0;
}

void create_magic_square(int n, int magic_square[][n]) {
    int i, j;

    printf("First\n");
    for(i = 0; i < n; ++i) {
        for(j = 0; j < n; ++j) {
            printf("%4d", magic_square[i][j]);
        }
        printf("\n\n");
    }

    //memset(magic_square, 0, n * sizeof(magic_square[0]));
    memset(magic_square, 0, sizeof(magic_square));

    printf("Before\n");
    for(i = 0; i < n; ++i) {
        for(j = 0; j < n; ++j) {
            printf("%4d", magic_square[i][j]);
        }
        printf("\n\n");
    }
}

在第二個代碼(帶有函數)中,我應該輸入以下行: memset (magic_square, 0, n * sizeof (magic_square [0])); 對於要清除的二維數組,同時使用: memset (magic_square, 0, sizeof (magic_square)); 不起作用。 為什么會這樣?

當您將 arrays 傳遞給 C 中的函數時,即使您在 function 原型中指定了數組類型,它們也會衰減為指向數組中第一個元素的指針。 因此sizeof將為您提供指針的大小,而不是數組的大小。

常見的做法是將數組大小與數組一起傳遞(可能作為size_t )並使用來編織你的魔法,例如:

int zeroArray(void *address, size_t sz) { // void* makes it clear
    memset(address, 0, sz);               // but int thing[][] would be same.
}
:
int xyzzy[42][7];
zeroArray(xyzzy, sizeof(xyzzy));

但是,您已經向當前的 function 傳遞了足夠的信息來執行此操作,特別是n 您應該能夠使用它來形成sizeof運算符的類型(可以采用變量類型),它將滿足您的需要:

memset(magic_square, 0, sizeof(int[n][n]));

(a)涵蓋在最新標准C116.3.2.1 Lvalues, arrays, and function designators /3部分下:

除非它是sizeof運算符、 _Alignof運算符或一元&運算符的操作數,或者是用於初始化數組的字符串文字,否則類型為 "array of type" 的表達式將轉換為類型為 "指向類型的指針”指向數組 object 的初始元素,並且不是左值。

盡管您有c99標簽,但我還是引用了該標准的最新迭代,唯一的區別是 C99 標准沒有提到Alignof ,因為它在該迭代中不存在。 除此之外,報價是相同的。

可以追溯到 K&R 第一版、 5.3 Pointers and arrays

實際上,對數組的引用被編譯器轉換為指向數組開頭的指針。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM