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

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

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

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

Q&A

解決済

2回答

23962閲覧

const修飾子での警告発生理由

setsu_tenhou

総合スコア33

C

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

0グッド

0クリップ

投稿2016/11/12 13:22

###前提・実現したいこと
c言語でハッシュテーブルのプログラムを組んでいます、見たことのない警告が出たので、出た理由をしりたく、質問します
###発生している問題・エラーメッセージ
ChainHash.c:14: warning: assignment discards qualifiers from pointer target type

###該当のソースコード #include <stdio.h> #include <stdlib.h> #include "Member.h" #include "ChainHash.h" /*ハッシュ関数*/ static int hash( int key, int size ) { return key % size; } /*ノードの各メンバに値を設定*/ static void SetNode( Node *n, const Member *x, const Node *next ) { n->data = *x; n->next = next; } /*ハッシュ表の初期化*/ int Initialize( ChainHash *h, int size ) { int i; if( ( h->table = calloc( size, sizeof( Node * ) ) ) == NULL ) { h->size = 0; return 0; } h->size = size; for( i = 0; i < size; i++ ) { h->table[ i ] = NULL; } return 1; } /*データの検索*/ Node *Search( const ChainHash *h, const Member *x ) { int key = hash( x->no, h->size ); Node *p = h->table[ key ]; /*着目ノード*/ while( p != NULL ) { if( p->data.no == x->no ) { return p; } p = p->next; } return NULL; /*探索失敗*/ } /*データの追加*/ int Add( ChainHash *h, const Member *x ) { int key = hash( x->no, h->size ); Node *p = h->table[ key ]; /*着目ノード*/ Node *temp; while( p != NULL ) { if( p->data.no == x->no ) { return 1; } p = p->next; } if( ( temp = calloc( h->size, sizeof( Node ) ) ) == NULL ) { return 2; } SetNode( temp, x, h->table[ key ] ); h->table[ key ] = temp; return 0; /*追加成功*/ } /*データの削除*/ int Remove( ChainHash *h, const Member *x ) { int key = hash( x->no, h->size ); Node *p = h->table[ key ]; /*着目ノード*/ Node **pp = &h->table[ key ]; /*着目ノードへのポインタ*/ while( p != NULL ) { if( p->data.no == x->no ) { *pp = p->next; free( p ); return 0; } pp = &p->next; p = p->next; } return 1; } /*ハッシュ表をダンプ*/ void Dump(const ChainHash *h ) { int i; Node *p = h->table[ i ]; for( i = 0; i < h->size; i++ ) { printf( "%02d " , i ); while( p != NULL ) { printf( "-> %d (%s) ", p->data.no, p->data.name ); p = p->next; } putchar( '\n' ); } } /*全データの削除*/ void Clear( ChainHash *h ) { int i; for( i = 0; i < h->size; i++ ) { Node *p = h->table [ i ]; while( p != NULL ) { Node *next = p->next; free( p ); p = next; } h->table[ i ] = NULL; } } /*ハッシュ表を後始末*/ void Terminate( ChainHash *h ) { Clear( h ); free( h->table ); h->size = 0; }

###試したこと
インターネットで調べてみたところ、なにやらconst修飾子が問題のようですが、しっくりくる、情報が見つけられませんでした。

###補足情報(言語/FW/ツール等のバージョンなど)
実行環境 : Centos6.5(final)
コンパイラ : gcc-4.4.7-4.el6.x86_64

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

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

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

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

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

guest

回答2

0

ベストアンサー

C

1static void SetNode( Node *n, const Member *x, const Node *next ) { 2 n->data = *x; 3 n->next = next; 4}

Node構造体のnextという変数が、constがついていないNode*型であることが理由です。
const Nodeへのポインタを、Nodeへのポインタに代入しようとしているのです。

C

1int i = 0; 2const int* p = &i; 3int* q; 4q = p; 5*q = 1;

上記のコードを見てください。pの中身は、constがついているので変わらない「はず」ですよね?
ですが、qを使うことで、中身を操作できてしまいます。
これが意図しないバグを生むことが多いため、constがついたポインタをそうでないポインタに代入しようとすると、警告が出るのです。

投稿2016/11/12 13:38

majiponi

総合スコア1720

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

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

setsu_tenhou

2016/11/12 14:43

丁寧に説明して下さり非常に助かりました しっかり理解できたつもりです。
guest

0

ここの238ページにわかりやすく書いているとおりです。
https://www.math.nagoya-u.ac.jp/~naito/lecture/2003_SS/PDF/02/C-1.pdf

投稿2016/11/12 13:48

hiim

総合スコア1689

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問