月別アーカイブ: 2015年4月

まず最初に(C/C++ 超入門)

C言語では「関数」を定義することでプログラミングします.
すなわち,関数 f(x,y,z) を評価すると,その定義として記述されたプログラムを実行します.

もう少しわかりやすく説明します.

tasu(x,y) := x + y

として関数 tasu を定義しますと,

a = tasu(1,2)

を計算(評価)することで変数 a に 3 が格納されます.
これをC言語で記述すると

int tasu(x,y)
int x,y;
{
	return(x+y);
}

となります.

C言語ではメインのプログラム本体も1つの関数 main として記述します.
例えば

int main()
{
	int a,b,c;
 
	a = 1;
	b = 2;
	c = a + b;
}

と記述して,これをコンパイルして実行すると,変数 c に 3 が格納されます.

先に定義した関数 tasu を main から呼び出すこともでき,

int main()
{
	int a,b,c;
 
	a = 1;
	b = 2;
	c = tasu(a,b);
}

と書くと a+b の結果が c に格納されます.

【ポインタと値】

C言語の初心者がまずはじめに悩むのが「ポインタ」です.
コンピュータ上のデータは変数などの記憶に格納されます.
ということは当然ですが,そのデータを格納している記憶域の「場所」があります.
また,コンピュータの記憶は1バイトづつ一直線に並んだ構造をしているので,
記憶の場所は「先頭から〜番目」という形で表現されます.

このように,記憶の「〜番目」を意味するものが「ポインタ」だと理解するとわかりやすいです.
言い換えると「記憶域のアドレス」の値がポインタであると言うこともできます.

変数のポインタ(アドレス)の値を得るには ‘&’ を使います.
すなわち,変数 a の格納場所の番地を求めるには &a とします.

例.記憶域の中での変数の場所(アドレス)を調べる
次のようなプログラムを作って実行してみましょう.

#include	<stdio.h>
 
int main()
{
	int	a = 3;
 
	printf("a = %d, address = %u\n",a,&amp;a);
}</stdio.h>

これを実行すると次のような表示になります.

a = 3, address = 1352710956

これはどういう意味かというと,
「変数 a には値 3 が入っており,それを格納している記憶域の番地(アドレス)は 1352710956 である」
ということです.

「ポインタ」はどんな場合に使うのか?
一言で「ポインタは〜に使う」とは言えないですが,よくある使用例を紹介します.
プログラムで扱うデータは,変数として扱うだけでは不便な場合があります.
例えば「データレコード」のような概念がありますが,それは複数の変数たちをまとめて1つの意味ある情報として扱う考え方です.C言語では「構造体」,C++では「クラス」というものがありますが,それらは「データレコード」を実現するものと考えることができます.

現実的なプログラミングでは,1つのアプリケーションをつくるために,幾つものサブルーチン(C/C++では関数)に分割して開発するのが普通です.分割された関数にデータレコードを引き渡す際にこのポインタが便利です.
どういうことかというと,関数にデータを渡す際に「データは記憶のこの番地においてある」という情報を相手関数に知らせるだけでよいということになり,データレコードの中身の全てを取り出して関数に送りつける必要がなくなるわけです.(わかります?)

ポインタの活用方法については,実際にプログラミングをしながら身につけて行きましょう.

【構造体】

C言語でデータレコードを実現するものとして構造体があります.
例えば次のようなプログラムを見てみましょう.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include	<stdio.h>
#include	<string.h>
 
typedef	struct {
	char	name[32];
	int	age;
	int	gender;	// 1:male, 2:female
	char	tel[24];
} PersonalInfo;
 
int main()
{
	PersonalInfo	db[100];
 
	strcpy( db[0].name, "Sato Taro" );
	db[0].age    = 29;
	db[0].gender = 1;
	strcpy( db[0].tel,  "123-4567" );
 
	printf("size of PersonalInfo:%lu, size of db:%lu bytes\n",
		sizeof(PersonalInfo),sizeof(db));
}</string.h></stdio.h>

このプログラムは個人情報を保持する簡単なデータベースを実現するものです.
氏名(name),年齢(age),性別(gender),電話番号(tel)を1つのまとまりとする構造体を記述し,それを PersonalInfo という型として定義しています.
main の中では PersonalInfo 型のレコードの配列 db を定義しています.また,PersonalInfo と db のデータサイズを出力しています.
実行例

size of PersonalInfo:64, size of db:6400 bytes

このように,構造体を用いると複数の変数からなるデータのまとまりを1つのレコードとして扱うことができます.

構造体の要素(メンバ)へのアクセス
上のプログラム例のように,ドット ‘.’ を使って構造体の要素(メンバ)にアクセスすることができます.

■■■ C++ ■■■

さて C++ ですが,基本的には C 言語の文法がベースになります.
なので「Cは勉強せずに,C++だけ学ぶ」というのはできません.(念のため)

ファイルの所有者・グループの設定

UNIXにおいてファイルの所有者や所属グループを変更するには chown 関数を呼び出します.
 
使い方: chown(ファイルのパス, ユーザID, グループID)
 
例えば,対象ファイルのパス名を格納する記憶へのポインタを char *p, ユーザIDが uid_t u に,グループIDが gid_t g に格納されているとき chown( p, u, g ) として実行します.
 
処理が正常に終了した場合,戻り値は0となります.
 
サンプルプログラム ファイル a の所有者・グループを設定する

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include	<stdio.h>
#include	<sys/types.h>
#include	<unistd.h>
 
int main()
{
	char	p[] = "a";
//	uid_t	uid = 501;
	uid_t	uid = 503;
	gid_t	gid = 20;
 
	if ( chown(p,uid,gid) != 0 ) {
		fprintf(stderr,"chown failed.\n");
	}
}