我試圖將陣列傳遞給方法。我嘗試了以下方法:
- func2(ARRAY_NAME, length) => WORKS,沒有警告
- func2(&ARRAY_NAME[0], length) => 作業,沒有警告
- func2(&ARRAY_NAME, length) => 作業,但有警告
我不明白為什么最后一個(#3)會發出警告。&ARRAY_NAME 在 memset、memcpy 等中作業時沒有警告。為什么它在自定義方法中有問題?
警告資訊:
functionTest.c:35:11: warning: passing argument 1 of ‘func2’ from incompatible pointer type [-Wincompatible-pointer-types]
35 | func2(&temp, ARRAY_SIZE);
| ^~~~~
| |
| unsigned char (*)[200]
functionTest.c:8:27: note: expected ‘unsigned char *’ but argument is of type ‘unsigned char (*)[200]’
8 | void func2(unsigned char* buf, int length)
代碼
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#define ARRAY_SIZE 200
void func2(unsigned char* buf, int length)
{
// Change data of any index
buf[0] = 100;
buf[10] = 200;
}
void func1()
{
unsigned char temp[ARRAY_SIZE];
// Initialize
memset(temp, 0, sizeof(temp));
for(int i = 0; i < ARRAY_SIZE; i )
{
printf("\t%d", temp[i]);
}
printf("\n-----------------------------------------------\n");
printf("Address : %p\n", &temp);
printf("Address of 0th index : %p\n", &temp[0]);
printf("\n-----------------------------------------------\n");
// Pass array in func2
func2(&temp, ARRAY_SIZE); // WARNING
func2(&temp[0], ARRAY_SIZE); // NO WARNING
for(int i = 0; i < ARRAY_SIZE; i )
{
printf("\t%d", temp[i]);
}
printf("\n-----------------------------------------------\n");
}
int main()
{
func1();
return 0;
}
uj5u.com熱心網友回復:
正如錯誤訊息中清楚寫的那樣
functionTest.c:8:27: note: expected ‘unsigned char *’ but argument is of type ‘unsigned char (*)[200]’
8 | void func2(unsigned char* buf, int length)
該函式需要一個該型別的指標,unsigned char *但引數運算式&temp具有該型別unsigned char ( * )[200],并且沒有從一種指標型別到另一種指標型別的隱式轉換,盡管指標的值相同:陣列占用的記憶體范圍的地址。
至于函式memset,memcpy然后它們處理型別的指標void *。例如該函式memset具有以下宣告
void *memset(void *s, int c, size_t n);
指向其他型別物件的指標可以隱式轉換為該型別的指標void *。
來自 C 標準(6.3.2.3 指標)
1 指向 void 的指標可以轉換為指向任何物件型別的指標或從指向任何物件型別的指標轉??換。指向任何物件型別的指標都可以轉換為指向 void 的指標并再次回傳;結果應與原始指標比較。
uj5u.com熱心網友回復:
func2被宣告為具有型別的第一個引數unsigned char *,因此應該傳遞一個指向兼容型別unsigned char的指標或指向 的指標void,該指標將自動轉換為unsigned char *.
使用func2(temp, ARRAY_SIZE)時,陣列temp會自動轉換為指向其第一個元素的指標。這個指標是一個unsigned char *,所以它滿足要求。
With func2(&temp[0], ARRAY_SIZE), temp[0]is an unsigned char, 所以&temp[0]是指向 an 的指標unsigned char。這滿足要求。
func2(&temp, ARRAY_SIZE)其中 ,是&temp一個指向 200 個元素的陣列的指標unsigned char。它與 指向同一個地方&temp[0],位其型別不同。它是指向陣列的指標,不是指向unsigned char或指向兼容型別的指標,也不是指向void. 所以它不滿足要求,編譯器抱怨。
指向陣列的指標unsigned char和指向陣列的指標是不同的。如果 is 的型別和ispu的unsigned char *型別(指向 200 的陣列的指標),則將 1 加到,如 in ,會產生指向下一個after的指標,但加 1 會產生指向下一個陣列 after 的指標。換句話說,指向記憶體中的下一個位元組,但指向記憶體中更遠的 200 個位元組。paunsigned char (*)[200]unsigned charpupu 1unsigned charpupapapu 1pa 1
C 型別系統的一個目的是幫助避免錯誤。當一個不匹配的型別被傳遞給一個函式時,程式員可能會期望一些不同于語言定義的行為。因此編譯器發出診斷訊息。
使用memset,它的第一個引數被宣告為void *。void是不完全型別;它充當其他型別的占位符。memset旨在處理任何物件的位元組,因此它接受指向任何物件型別的指標。當為引數傳遞任何指向物件型別的指標時void *,它會自動轉換為void *,而不會出現任何診斷訊息。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/480183.html
