天天看點

【C語言難弄關鍵字3】----void1.void解釋2.void修飾函數傳回和參數3.void指針

【C語言難弄關鍵字3】----void

1.void解釋

void字面意思為 空類型

void * 則為空類型的指針,void *可以指向任何資料類型的資料,但是沒有人會去定義一個void類型的變量。

[[email protected] keyword_study]$ cat define_Void.c
#include <stdio.h>

int main(int argc, char *charv[])
{
        void a;
        return 0;
}
[[email protected] keyword_study]$ gcc define_Void.c
define_Void.c: In function ‘main’:
define_Void.c:5: error: variable or field ‘a’ declared void
[[email protected] keyword_study]$
           

void的真正用途:

1)對函數傳回的限定;

2)對函數參數的限定;

我們知道,像這種情況,我們需要強制類型轉換 p1 = (float *)p2就可以了

[[email protected] keyword_study]$ cat define_Void.c
#include <stdio.h>

int main(int argc, char *charv[])
{
        float   *p1;
        int     *p2;
        p1 = p2;
        return  0;
}
[[email protected] keyword_study]$ gcc define_Void.c
define_Void.c: In function ‘main’:
define_Void.c:7: warning: assignment from incompatible pointer type
           

但,對于void的則顯然不用,任何類型的指針都可以指派給void的類型,無需強制類型轉換

[[email protected] keyword_study]$ cat define_Void.c
#include <stdio.h>

int main(int argc, char *charv[])
{
        void    *p1;
        int     *p2;
        p1 = p2;
        return  0;
}
[[email protected] keyword_study]$ gcc define_Void.c
           

但是,反過來昵?其他指針能轉成void類型嗎?答案是否定的

7    12    2018 秋招筆試真題\Untitled1.cpp    [Error] invalid conversion from 'void*' to 'int*' [-fpermissive]
           

2.void修飾函數傳回和參數

c語言中,凡是不加傳回值類型限定的函數,編譯器就會作為傳回整形處理。

[[email protected] keyword_study]$ cat return_Void.c
#include <stdio.h>

add_float(float a,float b)
{
        return  a+b;
}

int main(int argc, char *charv[])
{
        printf("add_float(2.1,3.2)=     %f\n",add_float(2.1,3.2));
        printf("add_float(2.1,3.2)=     %d\n",add_float(2.1,3.2));
        return  0;
}
[[email protected] keyword_study]$ gcc return_Void.c          
[[email protected] keyword_study]$ ./a.out          
add_float(2.1,3.2)=     0.000000
add_float(2.1,3.2)=     5
[[email protected] keyword_study]$
           

傳回值預設為整形,為了避免混亂,在編寫C語言程式時,必須指出其類型,如果沒有傳回值,一般設定為void類型。

3.void指針

3.1 算法運算能/不能?

ANSI規定void指針不能進行算法運算

[[email protected] keyword_study]$ cat pvoid.c
#include <stdio.h>

int main(int argc, char *charv[])
{
        void *pvoid;
        pvoid++;
        pvoid += 1;
        return  0;
}
[[email protected] keyword_study]$
           

具體報錯原因如下

7    14    \pvoid.cpp    [Error] ISO C++ forbids incrementing a pointer of type 'void*' [-fpermissive]
8    15    \pvoid.cpp    [Warning] pointer of type 'void *' used in arithmetic [-Wpointer-arith]
           

ANSI規定,進行算法操作的指針必須明确知道其指向資料類型的大小,也就是說必須知道記憶體目的位址的确切值。

即不為void的類型int,char等等都可以。但GNU規定void *運算同char *運算。

但是如果非要寫,兩者相容也并不是沒辦法,強轉一下編譯器還是報錯了

[[email protected] keyword_study]$ cat pvoid.c
#include <stdio.h>


int main(int argc, char *charv[])
{
        void *pvoid;
        (char *)pvoid++;
        (char *)pvoid += 1;
        return  0;
}
[[email protected] keyword_study]$ gcc pvoid.c
pvoid.c: In function ‘main’:
pvoid.c:8: error: lvalue required as left operand of assignment
[[email protected] keyword_study]$
           

3.2 函數參數未知設void *

如果函數參數可以為任意參數,那麼就設定為void *類型,可以參考memset和memcpy函數

void *memcpy(void *dest,const void *src,size_t len);
void *memset(void *buffer,int c,size_t num);
           

舉例:

1.将IntArray_a置0

int IntArray_a[100];
memset(IntArray_a,0,100*sizeof(int));
           

2.将srcIntArry_a拷貝給destIntArry_a

memcpy(destIntArry_a,destIntArry_a,100*sizeof(int));
           

3.3 void不能代表一個真實的變量

void a;
function(void a);
           

上述表達中,都不符合要求,編譯報錯。

注:本篇文章學習來自《c語言深度剖析》,侵權必删。

繼續閱讀