鍍金池/ 問答/C  C++/ C++ 與 C 中的函數(shù)指針

C++ 與 C 中的函數(shù)指針

相關(guān)代碼

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

void *print_message_function( void *ptr );

main()
{
     pthread_t thread1, thread2;
     const char *message1 = "Thread 1";
     const char *message2 = "Thread 2";
     int  iret1, iret2;

     iret1 = pthread_create( &thread1, NULL, print_message_function, (void*) message1);
     if(iret1)
     {
         fprintf(stderr,"Error - pthread_create() return code: %d\n",iret1);
         exit(EXIT_FAILURE);
     }

     iret2 = pthread_create( &thread2, NULL, print_message_function, (void*) message2);
     if(iret2)
     {
         fprintf(stderr,"Error - pthread_create() return code: %d\n",iret2);
         exit(EXIT_FAILURE);
     }

     printf("pthread_create() for thread 1 returns: %d\n",iret1);
     printf("pthread_create() for thread 2 returns: %d\n",iret2);

     pthread_join( thread1, NULL);
     pthread_join( thread2, NULL); 

     exit(EXIT_SUCCESS);
}

void *print_message_function( void *ptr )
{
     char *message;
     message = (char *) ptr;
     printf("%s \n", message);
}

疑惑地方

在函數(shù) pthread_create(pthread_t * thread, const pthread_attr_t * attr,void * (*start_routine)(void *), void *arg);
其中 void * (*start_routine)(void *) 這個(gè)參數(shù)是 "函數(shù)指針"
而根據(jù)函數(shù) void *print_message_function( void *ptr );原型來看這是一個(gè) 返回任何指針類型的函數(shù),不是函數(shù)指針,而且這個(gè)函數(shù)的實(shí)現(xiàn)中并沒有返回值. 但是可以使用gcc編譯通過,沒有任何異常, 有哪位知道這是為什么嗎? 或者給出一個(gè)參考鏈接?

我所知道的類似void *print_message_function( void *ptr ); 函數(shù)的用法是這樣的


 #include<stdio.h>

 void *test_f(int *n);
 
 int main(void) 
{
         int test_num = 32;
         int *test_p = &test_num;
         int *ret_v = test_f(test_p);
         printf("%d \n",*ret_v);
         return 0;
 }

void *test_f(int *n) 
{
         *n = *n + 1;
         return n;
}
回答
編輯回答
真難過

start_routine 參數(shù)的原型是

void *(*start_routine) (void *)

不是

void (start_routine)(void)

void (start_routine)(void*)

請(qǐng)參照文檔 http://man7.org/linux/man-pag...


默認(rèn)情況下,gcc 要開啟 -Wreturn-type 才會(huì)警告 “在非 void 返回值函數(shù)中沒有 return 語句”,
一般建議打開 -Wall 選項(xiàng),可將所有警告當(dāng)成編譯錯(cuò)誤,如

gcc -Wall a.c

若使用 g++ 編譯,則不必顯式指定 -Wreturn-type,因它規(guī)定要寫 return(對(duì)非 void 返回值)。

2018年1月13日 07:43
編輯回答
哚蕾咪

先說一個(gè)問題:你的最后一個(gè)函數(shù)void *test_f(int *n)中的return語句有問題,應(yīng)是return &n;

接下來回答你的疑惑——

首先你的void *print_message_function( void *ptr )函數(shù)的實(shí)現(xiàn)中,沒有顯式使用調(diào)用return語句,據(jù)我對(duì)一些編譯器的了解,編譯器會(huì)自動(dòng)設(shè)置一個(gè)返回值并返回,通常是0。編譯時(shí)這樣的情況通常會(huì)報(bào)出warning錯(cuò)誤的,如果你沒有看到相關(guān)報(bào)錯(cuò),可能是編譯器禁用了相關(guān)報(bào)錯(cuò)。

然后是函數(shù)指針。C里邊,數(shù)組和函數(shù)有一個(gè)共同的有趣特性,如下代碼所示:

#include <stdio.h>

int list[10];
int func() {}

int main()
{
    printf("%x\n", list);
    printf("%x\n", &list);
    printf("%x\n", func);
    printf("%x\n", &func);
    printf("%x\n", sizeof func);
    return 0;
}

這段代碼在我的電腦(CentOS 7.4, gcc 4.8.5)上運(yùn)行結(jié)果如下:

601060
601060
40051d
40051d
1

從前四行可以看出,不管是數(shù)組和函數(shù)的標(biāo)識(shí)符本身,還是對(duì)它們?nèi)〉刂?,其結(jié)果是一樣的。從這種意義上講,函數(shù)名就是一個(gè)類似于指針的存在,函數(shù)名本身和指向這個(gè)函數(shù)的指針在使用上是具有相似性的。但是sizeof func的值竟然是1,這也說明函數(shù)又絕對(duì)不是簡(jiǎn)單的指針。至于C語言的函數(shù)本質(zhì)究竟是什么樣的,由于我對(duì)C語言的標(biāo)準(zhǔn)、編譯原理、GCC實(shí)現(xiàn)原理沒有什么研究,因此還解釋不了這個(gè)問題,但以上應(yīng)該基本可以回答pthread_create調(diào)用函數(shù)這個(gè)問題了。

2017年7月17日 10:36