ポインタvoid *およびvoid **などに関するいくつかの理解と疑問。

最近の勉強ではいつもポインター操作に出くわしました。基礎が弱いので、たくさんの情報を参考にした後も、まだ複数のポインターのグループがあります。今はポインターについての理解と疑問を書き留めています。ネチズンが助けてくれることを願っています。私は私にいくつかのポインタを与えます。

まず、void *は、どのタイプのデータも指さないvoid型のポインターを定義します。つまり、voidポインターは「空の型を指す」または「特定の型を指さない」ので、そうすべきではありません。 voidポインタは「任意のタイプ」「データを指すことができると理解されます。つまり、voidはアドレスのみを提供し、ポイントは提供しません。非voidポインタをvoidポインタに割り当てることはできますが、voidポインタを非voidポインタに直接割り当てることはできません。最初に強制する必要があります。例えば:

void *pv;
char *pc;
char c = 'c';

pc = &c;
pv = pc;        //合法
pc = pv;        //非法,void*指针不能直接赋值给非void指针
pc = (char*)pv; //合法,把void*指针强转成char*型后在赋值

複数のポインターの場合、**はポインターへのポインターと同等です。これは本質的にポインターですが、アドレスを指します。&は非常に単純です。つまり、右から左へ、最初にアドレスと操作、次にポインタ操作という同じレベルの操作です。例えば:

int i1 = 1;
void *pv1 = &i1;
void **ppv1 = &pv1;
int **ppout;

ここで、ppv1がアドレス値、* ppv1もアドレス値、** ppv1がi1の実際の値であることがわかります。

OK - - - - - - - - - - - - - - - - - - - - - - - - - ---------------------

上記はvoid *とvoid **の簡単な理解です。簡単な例を見てみましょう。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <errno.h>

struct thrd{
    
    
	int var;
	char str[256];
};

void sys_err(const char *str)
{
    
    
    perror(str);
    exit(1);
}
  
void *tfn(void *arg)
{
    
    
	struct thrd *tval;

	tval = malloc(sizeof(tval));
	tval->var = 100;
	strcpy(tval->str, "hello thread");

	return (void *)tval;
}

int main(int argc, char *argv[])
{
    
    
    pthread_t tid;
	struct thrd *retval;

	int ret = pthread_create(&tid, NULL, tfn, NULL);
	if(ret != 0)
		sys_err("pthread_create error");

	ret = pthread_join(tid, (void **)&retval);
	if(ret != 0)
		sys_err("pthread_join error");

	printf("child thread exit with var = %d,str = %s\n", retval->var, retval->str);

    pthread_exit(NULL);
}

Linuxシェルターミナルでマルチスレッドプログラムを作成するとき、主にint pthread_join(pthread_t thread、void ** retval);について理解できないことがたくさんあります。この関数は理解できません。これは、誰にとっても便利です。プログラムを読むために。プログラムの機能は非常に単純です。intpthread_create(pthread_t * thread、const pthread_attr_t * attr、void *(* start_routine)(void *)、void * arg);を使用します。リサイクルスレッドはによってブロックされます。 pthread_join、そして最後にサブスレッド関数で割り当てられた構造がメインスレッドで出力されます。ここで私が持っている最大の疑問は、サブスレッドを取得するためにvoid **タイプのパラメーターを使用するpthread_joinの2番目のパラメーターです。戻り値スレッドの中で、なぜダブルポインタを使ってパラメータを渡すのかわからないところがありますが、この場所を削除した後、長い間考えてみたところ、threadvoidによって呼び出される関数の戻り値がわかりました。 * tfn(void * arg)タイプvoid *のポインターの場合、戻り値tvalはreturn(void *)tvalによってタイプをvoid *に強制的に変更し、&retvalに割り当てられるため、retvalのアドレスはtvalを指します。 (個人的な理解:ここ(void **)は、&retvalを2つのダブルポインターとして宣言することです。この時点で括弧を追加することは、変数タイプが宣言されていることを除いて、括弧なしでダブルポインターを定義することと同じです。*記号は変数を読み取りません。 )、そしてtvalの値はretvalを介してアクセスできます。説明は非常に遠いです、記事それは大物の意見を調べるために送信されました。私はここのポインタを本当に理解していません。あなたが知っているなら大物、教えてください!

おすすめ

転載: blog.csdn.net/qq_42955211/article/details/113100335