質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

3回答

1313閲覧

C言語 if文 条件式

hogeee

総合スコア27

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2020/09/24 02:56

c

1#include <unistd.h> 2#include <sys/mman.h> 3#include <time.h> 4#include <stdio.h> 5#include <stdlib.h> 6#include <err.h> 7 8#define CACHE_LINE_SIZE 64 9#define NLOOP (4 * 1024UL * 1024 * 1024) 10#define NSECS_PER_SEC 1000000000UL 11 12static inline long diff_nsec(struct timespec before, struct timespec after) { 13 return ((after.tv_sec * NSECS_PER_SEC | after.tv_nsec) 14 - (before.tv_sec * NSECS_PER_SEC + before.tv_nsec)); 15} 16 17int main(int argc, char *argv[]) 18{ 19 char *progname; 20 progname = argv[0]; 21 22 if (argc != 2) { 23 fprintf(stderr, "usage: %s <size[KB]>\n", progname); 24 exit(EXIT_FAILURE); 25 } 26 27 register int size; 28 size = atoi(argv[1]) * 1024; 29 if (!size) { 30 fprintf(stderr, "size should be >= 1; %d\n", size); 31 exit(EXIT_FAILURE); 32 } 33 34 char *buffer; 35 buffer = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 36 if (buffer == (void *) -1) 37 err(EXIT_FAILURE, "mmap() failed"); 38 39 struct timespec before, after; 40 41 clock_gettime(CLOCK_MONOTONIC, &before); 42 43 int i; 44 for (i = 0; i < NLOOP / (size / CACHE_LINE_SIZE); i++) { 45 long j; 46 for (j = 0; j < size; j += CACHE_LINE_SIZE) 47 buffer[j] = 0; 48 } 49 50 clock_gettime(CLOCK_MONOTONIC, &after); 51 52 printf("%f\n", (double)diff_nsec(before, after) / NLOOP); 53 54 if (munmap(buffer, size) == -1) 55 err(EXIT_FAILURE, "munmap() failed"); 56 exit(EXIT_SUCCESS); 57} 58

このコードはキャッシュメモリの影響により、プロセスがアクセスするデータサイズによってデータアクセス時間がどのように変化するか見るプログラムです。

質問は、この部分です。

c

1 if (buffer == (void *) -1) 2 err(EXIT_FAILURE, "mmap() failed"); 3

このif文の条件式はbufferが何と等しいとき分岐するのでしょうか?
(void *) -1の意味がわかりません。
void * のあとには変数が指定される気がするのですが、特に指定されていないようです。なぜこれでうまく行くのでしょうか。
よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

void * のあとには変数が指定される気がする

これは型の宣言文ではなく、キャストです。

int i=1; とすれば、iはintですが、
(double)i とすれば、iをdoubleの1.0として扱います。

これは別に変数に限ったことではなく、
1 と書けばint型のリテラルですが、
(double)1 とかけば、double型のリテラル1.0になります。
(1.0と書いたのと同じ)

void* とは、型指定のないポインタつまりはアドレスです。
(void *)-1 とは、アドレス-1へのポインタとなります。
(実際にはアドレスにマイナスはないので、0xffffや0xffffffffへのポインタになると思います)

そのアドレスそのものには意味は無くて、既に書かれているように、返り値が-1であり、その型がvoid *型なので、それに合わせているのです。

投稿2020/09/24 07:53

amiya

総合スコア1218

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

(void *) -1の意味がわかりません。

書いての通り、「ポインタ型としての-1」です。mmapはマッピングに失敗した場合、そのような値を返します。

失敗すると値 MAP_FAILED (つまり (void *) -1) を返し、 errno がエラーの内容にしたがってセットされる。 (manより)

投稿2020/09/24 03:05

maisumakun

総合スコア145183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

このif文の条件式はbufferが何と等しいとき分岐するのでしょうか?

mmapとかいうやつに関して検索すると
「この関数の戻り値は void* 型であり,失敗時には-1が返る」とかいう話が見つかりましたので,
mmapなる関数が失敗したときでしょう.

(void *) -1の意味がわかりません。

-1(int型かな)を void* 型にキャストしています.

投稿2020/09/24 03:04

fana

総合スコア11645

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問