Powered by SmartDoc

ソフトウェア概論B (2010/11/26)
Ver. 1.0

2010年11月26日
栗野 俊一
kurino@math.cst.nihon-u.ac.jp
http://edu-gw2.math.cst.nihon-u.ac.jp/~kurino/2010/soft/soft.html
ソフトウェア概論 B2010年11月26日 の資料

目次

講義資料

当日の OHP 資料

当日のOHP資料です。

本日の概要

10.ポインター( Text p.226 - 245 )

講義で利用するサンプルプログラム

sample-005

Download : sample-005.c ( SJIS 版 )

sample-005.c
#include <stdio.h>

void sub ( int arg ) {

  printf ( "sub:\n" );

  printf ( "\targ == %d\n", arg );
  printf ( "\t&arg == %p\n", &arg );

  arg = arg * 10;

  printf ( "\targ == %d\n", arg );

}


int func ( int arg ) {

  printf ( "func:\n" );

  printf ( "\targ == %d\n", arg );
  printf ( "\t&arg == %p\n", &arg );

  arg = arg * 10;

  printf ( "\targ == %d\n", arg );

  return arg;
}


int main ( void ) {
  int iv = 5;

  printf ( "&iv == %p\n", &iv );

  printf ( "iv == %d\n", iv );

  sub ( iv );

  printf ( "iv == %d\n", iv );

  iv = func ( iv );

  printf ( "iv == %d\n", iv );

  return 0;
}
sample-005.c の実行結果
C:\usr\c\> sample-005
&iv == 0xbfb80b8c
iv == 5
sub:
	arg == 5
	&arg == 0xbfb80b70
	arg == 50
iv == 5
func:
	arg == 5
	&arg == 0xbfb80b70
	arg == 50
iv == 50
C:\usr\c\> 

sample-006

Download : sample-006.c ( SJIS 版 )

sample-006.c
#include <stdio.h>

void without_pointer( int arg ) {

  printf ( "without pointer:\n" );

  printf ( "\targ == %d\n", arg );

  arg = arg * 10;

  printf ( "\targ == %d\n", arg );

}

void with_pointer( int *argp ) {

  printf ( "with pointer:\n" );

  printf ( "\t*argp == %d\n", *argp );

  *argp = *argp * 10;

  printf ( "\t*argp == %d\n", *argp );

}

int main ( void ) {
  int iv = 5;

  printf ( "iv == %d\n", iv );

  without_pointer( iv );

  printf ( "iv == %d\n", iv );

  with_pointer( &iv );

  printf ( "iv == %d\n", iv );

  return 0;
}
sample-006.c の実行結果
C:\usr\c\> sample-006
iv == 5
without pointer:
	arg == 5
	arg == 50
iv == 5
with pointer:
	*argp == 5
	*argp == 50
iv == 50
C:\usr\c\> 

sample-007

Download : sample-007.c ( SJIS 版 )

sample-007.c
#include <stdio.h>

void my_char_scanf ( char *cp ) {

  printf ( "Input char : " );
  scanf ( "%c", cp );
}

void my_int_scanf ( int *ip ) {

  printf ( "Input int : " );
  scanf ( "%d", ip );
}

void my_double_scanf ( double *dp ) {

  printf ( "Input double : " );
  scanf ( "%lf", dp );
}


int main ( void ) {
  char cv;
  int iv;
  double dv;

  my_char_scanf ( &cv );
  printf ( "Input char is %c\n", cv );

  my_int_scanf ( &iv );
  printf ( "Input int is %d\n", iv );

  my_double_scanf ( &dv );
  printf ( "Input double is %f\n", dv );
  
  return 0;
}
入力例
x
12
3.14
sample-007.c の実行結果
C:\usr\c\> sample-007
Input char : x
Input char is x
Input int : 12
Input int is 12
Input double : 3.140000
Input double is 3.140000
C:\usr\c\> 

sample-008

Download : sample-008.c ( SJIS 版 )

sample-008.c
#include <stdio.h>

int main ( void ) {
  int iv;

  /* */

  printf ( "Pointer\n" );

  iv = 0x12345678;
  printf ( "Before: iv == %x\n", iv );

  *((char *)&iv) = '0';
  printf ( "After: iv == %x\n", iv );

  printf ( "\n" );

  /* */

  printf ( "Scanf\n" );

  iv = 0x12345678;
  printf ( "Before: iv == %x\n", iv );

  printf ( "Please input '0' then [ENTER] : \n" );
  scanf ( "%c", &iv );

  printf ( "After: iv == %x\n", iv );

  /* */
  
  return 0;
}
入力例
0
sample-008.c の実行結果
C:\usr\c\> sample-008
Pointer
Before: iv == 12345678
After: iv == 12345630

Scanf
Before: iv == 12345678
Please input '0' then [ENTER] : 
0
After: iv == 12345630
C:\usr\c\> 

sample-009

Download : sample-009.c ( SJIS 版 )

sample-009.c
#include <stdio.h>

int main ( void ) {
  int ia[10];

  printf ( "ia == %p\n", ia );
  printf ( "&ia[0] == %p\n", &ia[0] );

  return 0;
}
sample-009.c の実行結果
C:\usr\c\> sample-009
ia == 0xbfd82da8
&ia[0] == 0xbfd82da8
C:\usr\c\> 

sample-010

Download : sample-010.c ( SJIS 版 )

sample-010.c
#include <stdio.h>

int main ( void ) {
  int ia[10];
  int *ip;

  /* */

  ip = ia; /* ip = &a[0] と同じ */

  /* */

  ia[0] = 123;

  printf ( "*ip == %d\n", *ip ); /* ip == &a[0] より *ip == *&a[0] == ia[0] */
  printf ( "*ia == %d\n", *ia ); /* ia == &a[0] より *ia == *&a[0] == ia[0] */

  /* */

  ia[1] = 456;

  printf ( "ip[1] == %d\n", ip[1] ); /* ip[1] == ia[1] */

  /* */

  *(ip + 3) = 789;			/* *(ip+3) == ip[3] == ia[3] */

  printf ( "ia[3] == %d\n", ia[3] );

  /* */

  printf ( "3[ip] == %d\n", 3[ip] );	/* はぁ ?              */
  					/* 3[ip] == *(3 + ip) */
					/*       == *(ip + 3) */
                                        /*       == ip[3]     */

  /* */

  printf ( "*(ip+10) == %d\n", *(ip+10) ); /* ポインターの危い利用法 */
  printf ( "ia[10] == %d\n", ia[10] );     /* 配列だって同じく危い */

  /* */

  return 0;
}
sample-010.c の実行結果
C:\usr\c\> sample-010
*ip == 123
*ia == 123
ip[1] == 456
ia[3] == 789
3[ip] == 789
*(ip+10) == -1077009228
ia[10] == -1077009228
C:\usr\c\> 

sample-011

Download : sample-011.c ( SJIS 版 )

sample-011.c
#include <stdio.h>

int main ( void ) {
  char line[10] = "abcdefg";

  scanf ( "%s", line + 3 ); /* "xy" と入力すると.. */

  printf ( "%s\n", line ); /* "abcxy" と後の部分だけが上書きされる */

  printf ( "line[6]=%c\n", line[6] ); /* 'g' はまだ、残っている */

  return 0;
}
入力例
xy
sample-011.c の実行結果
C:\usr\c\> sample-011
xy
abcxy
line[6]=g
C:\usr\c\> 

sample-012

Download : sample-012.c ( SJIS 版 )

sample-012.c
#include <stdio.h>

int main ( void ) {
  char line[10];

  /* scanf */

  scanf ( "%9s", line );	/* 入力文字数を指定 */
  printf ( "「%s」\n", line );	/* 指定した文字数だけ入力した */

  scanf ( "%9s", line );
  printf ( "「%s」\n", line );	/* 残りの文字は改行の直前まで後から読み取れる */

  /* 改行が残っている */

  getchar();			/* 改行を読み飛ばす */

  /* fgets */

  fgets ( line, 9, stdin );	/* 指定した文字数だけ入力 */
  printf ( "「%s」\n", line );

  fgets ( line, 9, stdin );	/* 残りの文字は、改行も読み込まれる */
  printf ( "「%s」\n", line );

  return 0;
}
入力例
abcdefghijklmn
abcdefghijklmn
sample-012.c の実行結果
C:\usr\c\> sample-012
abcdefghi
「abcdefghi」
jklmn
「jklmn」
「abcdefgh」
「ijklmn
」
C:\usr\c\> 

sample-013

Download : sample-013.c ( SJIS 版 )

sample-013.c
#include <stdio.h>

#define EOS '\0'

void add_123_with_pointer ( int *ptr ) {

  *ptr++ = 1;
  *ptr++ = 2;
  *ptr++ = 3;

}

#define ENOGH_SIZE 100

int main ( void ) {
  int ia[ENOGH_SIZE];
  int *ip;
  
  for ( ip = ia; ip < ia + ENOGH_SIZE - 3; ip = ip + 3 ) {
    add_123_with_pointer ( ip );
  }
  *ip = 0;

  for ( ip = ia; *ip > 0; ip++ ) {
    printf ( "%d\n", *ip );
  }

  return 0;
}
sample-013.c の実行結果
C:\usr\c\> sample-013
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
C:\usr\c\> 

sample-014

Download : sample-014.c ( SJIS 版 )

sample-014.c
#include <stdio.h>

void add_123_without_pointer ( int ia[], int start ) {

  ia[start++] = 1;
  ia[start++] = 2;
  ia[start++] = 3;

}

#define ENOGH_SIZE 100

int main ( void ) {
  int ia[ENOGH_SIZE];
  int ii;
  
  for ( ii = 0; ii < ENOGH_SIZE - 3; ii = ii + 3 ) {
    add_123_without_pointer ( ia, ii );
  }
  ia[ii] = 0;

  for ( ii = 9; ia[ii] > 0; ii++ ) {
    printf ( "%d\n", ia[ii] );
  }

  return 0;
}
sample-014.c の実行結果
C:\usr\c\> sample-014
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
1
2
3
C:\usr\c\> 

講議中に作成したプログラム

本日の課題

[問題]配列の利用した教科書の次のサンプルプログラム内の配列参照の部分を全て、ポインターを用いた形に書換えなさい。

次の例題に従って、テキストの次の課題の指定した配列をそれぞれポインター変数に書き換えて、実行結果が変らない事を確認しなさい。

課題プログラム内の「/*名前:ここ*/」の部分を書き換えてプログラムを完成させます。なお「名前」の部分が同じ所には同じものが入ります。

課題 20101126-01

Download : 20101126-01.c ( SJIS 版 )

20101126-01.c
/*
 * 課題 20101126-01
 */

#include<stdio.h>

#define ARRAY_SIZE	5

int main(void)
{
  int vc[ARRAY_SIZE];	/* 要素数が ARRAY_SIZE(5) の配列 */

  /* 0:ここ */ = 1;
  /* 1:ここ */ = 2;
  /* 2:ここ */ = 3;
  /* 3:ここ */ = 4;
  /* 4:ここ */ = 5;

  printf ( "vc[0] = %d\n", /* 0:ここ */ );
  printf ( "vc[1] = %d\n", /* 1:ここ */ );
  printf ( "vc[2] = %d\n", /* 2:ここ */ );
  printf ( "vc[3] = %d\n", /* 3:ここ */ );
  printf ( "vc[4] = %d\n", /* 4:ここ */ );

  return 0;
}
20101126-01.c の実行結果
C:\usr\c\> 20101126-01
vc[0] = 1
vc[1] = 2
vc[2] = 3
vc[3] = 4
vc[4] = 5
C:\usr\c\> 
参考[List 5-2 (Text p.90)]
Download : [List 5-2 (Text p.90)]
[List 5-2 (Text p.90)]
/*
 * List 5-2 (Text p.90)
 */

#include<stdio.h>

#define ARRAY_SIZE	5

int main(void)
{
  int vc[ARRAY_SIZE];	/* 要素数が ARRAY_SIZE(5) の配列 */

  vc[0] = 1;
  vc[1] = 2;
  vc[2] = 3;
  vc[3] = 4;
  vc[4] = 5;

  printf ( "vc[0] = %d\n", vc[0] );
  printf ( "vc[1] = %d\n", vc[1] );
  printf ( "vc[2] = %d\n", vc[2] );
  printf ( "vc[3] = %d\n", vc[3] );
  printf ( "vc[4] = %d\n", vc[4] );

  return 0;
}

課題 20101126-02

Download : 20101126-02.c ( SJIS 版 )

20101126-02.c
/*
 * 課題 20101126-02
 */

#include<stdio.h>

#define ARRAY_SIZE	5

int main(void)
{
  int va[ARRAY_SIZE] = { 15, 20, 30 };	/* 要素数が ARRAY_SIZE(5) の配列 */
  int vb[ARRAY_SIZE];
  int i;

  for ( i = 0; i < ARRAY_SIZE; i++ ) {
	/* b:ここ */ = /* a:ここ */;
  }

  printf ( " va vb\n" );
  printf ( "------\n" );
  for ( i = 0; i < ARRAY_SIZE; i++ ) {
	printf ( "%3d%3d\n", /* a:ここ */, /* b:ここ */ );
  }

  return 0;
}
20101126-02.c の実行結果
C:\usr\c\> 20101126-02
 va vb
------
 15 15
 20 20
 30 30
  0  0
  0  0
C:\usr\c\> 
参考[List 5-6 (Text p.93)]
Download : [List 5-6 (Text p.93)]
[List 5-6 (Text p.93)]
/*
 * List 5-6 (Text p.93)
 */

#include<stdio.h>

#define ARRAY_SIZE	5

int main(void)
{
  int va[ARRAY_SIZE] = { 15, 20, 30 };	/* 要素数が ARRAY_SIZE(5) の配列 */
  int vb[ARRAY_SIZE];
  int i;

  for ( i = 0; i < ARRAY_SIZE; i++ ) {
	vb[i] = va[i];
  }

  printf ( " va vb\n" );
  printf ( "------\n" );
  for ( i = 0; i < ARRAY_SIZE; i++ ) {
	printf ( "%3d%3d\n", va[i], vb[i] );
  }

  return 0;
}

課題 20101126-03

Download : 20101126-03.c ( SJIS 版 )

20101126-03.c
/*
 * 英語の点数と数学の点数の最高点を求める
 * 課題 20101126-03
 */

#include<stdio.h>

#define NUMBER_OF_POINT	5

/*
 * 要素数 no の配列 vc の最大値を求め、その結果を返す
 */

int max_of ( int /* a:ここ */, int no ) {
  int i;
  int max = /* a:ここ */;

  for ( i = 1; i < no; i++ ) {
	if ( /* b:ここ */ > max ) {
	  max = /* b:ここ */;
	}
  }

  return max;
}

/*
 * main
 */

int main(void)
{
  int eng[NUMBER_OF_POINT];	/* 英語の点数 */
  int max_e;			/* 英語の最高点 */

  int mat[NUMBER_OF_POINT];	/* 数学の点数 */
  int max_m;			/* 数学の最高点 */

  int i;

  printf ( "%d 人の点数を入力してください。\n", NUMBER_OF_POINT );

  for ( i = 0; i < NUMBER_OF_POINT; i++ ) {
	printf ( "[%d] 英語 : ", i + 1 );
	scanf ( "%d", &eng[i] );
	printf ( "     数学 : " );
	scanf ( "%d", &mat[i] );
  }

  max_e = max_of ( eng, NUMBER_OF_POINT );
  max_m = max_of ( mat, NUMBER_OF_POINT );

  printf ( "英語の最高点 = %d\n", max_e );
  printf ( "数学の最高点 = %d\n", max_m );

  return 0;
}
入力例
53
82
49
35
21
72
91
35
77
12
20101126-03.c の実行結果
C:\usr\c\> 20101126-03
5 人の点数を入力してください。
[1] 英語 : 53
     数学 : 82
[2] 英語 : 49
     数学 : 35
[3] 英語 : 21
     数学 : 72
[4] 英語 : 91
     数学 : 35
[5] 英語 : 77
     数学 : 12
英語の最高点 = 91
数学の最高点 = 82
C:\usr\c\> 
参考[List 6-11 (Text p.130)]
Download : [List 6-11 (Text p.130)]
[List 6-11 (Text p.130)]
/*
 * 英語の点数と数学の点数の最高点を求める
 * List 6-11 (Text p.130)
 */

#include<stdio.h>

#define NUMBER_OF_POINT	5

/*
 * 要素数 no の配列 vc の最大値を求め、その結果を返す
 */

int max_of ( int vc[], int no ) {
  int i;
  int max = vc[0];

  for ( i = 1; i < no; i++ ) {
	if ( vc[i] > max ) {
	  max = vc[i];
	}
  }

  return max;
}

/*
 * main
 */

int main(void)
{
  int eng[NUMBER_OF_POINT];	/* 英語の点数 */
  int max_e;			/* 英語の最高点 */

  int mat[NUMBER_OF_POINT];	/* 数学の点数 */
  int max_m;			/* 数学の最高点 */

  int i;

  printf ( "%d 人の点数を入力してください。\n", NUMBER_OF_POINT );

  for ( i = 0; i < NUMBER_OF_POINT; i++ ) {
	printf ( "[%d] 英語 : ", i + 1 );
	scanf ( "%d", &eng[i] );
	printf ( "     数学 : " );
	scanf ( "%d", &mat[i] );
  }

  max_e = max_of ( eng, NUMBER_OF_POINT );
  max_m = max_of ( mat, NUMBER_OF_POINT );

  printf ( "英語の最高点 = %d\n", max_e );
  printf ( "数学の最高点 = %d\n", max_m );

  return 0;
}