Powered by SmartDoc

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

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

目次

講義資料

当日の OHP 資料

当日のOHP資料です。

本日の概要

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

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

sample-001

Download : sample-001.c ( SJIS 版 )

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

void char_pointer_calc ( void ) {
  char cv;

  printf ( "char 型:\n" );
  printf ( "\tsizeof(char) == %d\n", sizeof( char ) );

  printf ( "\tchar cv;\n" );
  printf ( "\t&cv == %p\n", &cv );
  printf ( "\t&cv + 1 == %p\n", &cv + 1 );
  printf ( "\t&cv + 2 == %p\n", &cv + 2 );

  printf ( "\t((char *)0x10000)     == %p\n", ((char *)0x10000) );
  printf ( "\t((char *)0x10000) + 1 == %p\n", ((char *)0x10000) + 1 );
  printf ( "\t((char *)0x10000) + 2 == %p\n", ((char *)0x10000) + 2 );

  printf ( "\t((char *)%p) - ((char *)%p) == %d\n",
	   ((char *)(0x10000 + 8)),
	   ((char *)(0x10000)),
	   ((char *)(0x10000 + 8)) - ((char *)(0x10000)) );

  printf ( "\n" );

}

void int_pointer_calc ( void ) {
  int iv;

  printf ( "int 型:\n" );
  printf ( "\tsizeof(int) == %d\n", sizeof( int ) );
  printf ( "\tint iv;\n" );
  printf ( "\t&iv == %p\n", &iv );
  printf ( "\t&iv + 1 == %p\n", &iv + 1 );
  printf ( "\t&iv + 2 == %p\n", &iv + 2 );

  printf ( "\t((int *)0x10000)     == %p\n", ((int *)0x10000) );
  printf ( "\t((int *)0x10000) + 1 == %p\n", ((int *)0x10000) + 1 );
  printf ( "\t((int *)0x10000) + 2 == %p\n", ((int *)0x10000) + 2 );

  printf ( "\t((int *)%p) - ((int *)%p) == %d\n",
	   ((int *)(0x10000 + 8)),
	   ((int *)(0x10000)),
	   ((int *)(0x10000 + 8)) - ((int *)(0x10000)) );

  printf ( "\n" );

}

void double_pointer_calc ( void ) {
  double dv;

  printf ( "double 型:\n" );
  printf ( "\tsizeof(double) == %d\n", sizeof( double ) );
  printf ( "\tdouble dv;\n" );
  printf ( "\t&dv == %p\n", &dv );
  printf ( "\t&dv + 1 == %p\n", &dv + 1 );
  printf ( "\t&dv + 2 == %p\n", &dv + 2 );

  printf ( "\t((double *)0x10000)     == %p\n", ((double *)0x10000) );
  printf ( "\t((double *)0x10000) + 1 == %p\n", ((double *)0x10000) + 1 );
  printf ( "\t((double *)0x10000) + 2 == %p\n", ((double *)0x10000) + 2 );

  printf ( "\t((double *)%p) - ((double *)%p) == %d\n",
	   ((double *)(0x10000 + 8)),
	   ((double *)(0x10000)),
	   ((double *)(0x10000 + 8)) - ((double *)(0x10000)) );

  printf ( "\n" );

}

int main ( void ) {

  printf ( "\t\tpointer calculation\n" );

  char_pointer_calc();
  int_pointer_calc();
  double_pointer_calc();

  return 0;
}
sample-001.c の実行結果
C:\usr\c\> sample-001
		pointer calculation
char 型:
	sizeof(char) == 1
	char cv;
	&cv == 0xbff0e5df
	&cv + 1 == 0xbff0e5e0
	&cv + 2 == 0xbff0e5e1
	((char *)0x10000)     == 0x10000
	((char *)0x10000) + 1 == 0x10001
	((char *)0x10000) + 2 == 0x10002
	((char *)0x10008) - ((char *)0x10000) == 8

int 型:
	sizeof(int) == 4
	int iv;
	&iv == 0xbff0e5dc
	&iv + 1 == 0xbff0e5e0
	&iv + 2 == 0xbff0e5e4
	((int *)0x10000)     == 0x10000
	((int *)0x10000) + 1 == 0x10004
	((int *)0x10000) + 2 == 0x10008
	((int *)0x10008) - ((int *)0x10000) == 2

double 型:
	sizeof(double) == 8
	double dv;
	&dv == 0xbff0e5d8
	&dv + 1 == 0xbff0e5e0
	&dv + 2 == 0xbff0e5e8
	((double *)0x10000)     == 0x10000
	((double *)0x10000) + 1 == 0x10008
	((double *)0x10000) + 2 == 0x10010
	((double *)0x10008) - ((double *)0x10000) == 1

C:\usr\c\> 

sample-002

Download : sample-002.c ( SJIS 版 )

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

int main ( void ) {
  double dv;

  printf ( "sizeof(double)=%d\n", sizeof(double) );
  printf ( "&dv == %p\n", &dv );
  printf ( "&dv + 1 == %p\n", &dv + 1 );
  printf ( "&dv + 2 == %p\n", &dv + 2 );

  printf ( "sizeof(int)=%d\n", sizeof(int) );
  printf ( "((int *)&dv) == %p\n", (int *)&dv );
  printf ( "((int *)&dv) + 1 == %p\n", ((int *)&dv) + 1 );
  printf ( "((int *)&dv) + 2 == %p\n", ((int *)&dv) + 2 );

  printf ( "sizeof(char)=%d\n", sizeof(char) );
  printf ( "((char *)&dv) == %p\n", (char *)&dv );
  printf ( "((char *)&dv) + 1 == %p\n", ((char *)&dv) + 1 );
  printf ( "((char *)&dv) + 2 == %p\n", ((char *)&dv) + 2 );

  return 0;

}
sample-002.c の実行結果
C:\usr\c\> sample-002
sizeof(double)=8
&dv == 0xbfbfc808
&dv + 1 == 0xbfbfc810
&dv + 2 == 0xbfbfc818
sizeof(int)=4
((int *)&dv) == 0xbfbfc808
((int *)&dv) + 1 == 0xbfbfc80c
((int *)&dv) + 2 == 0xbfbfc810
sizeof(char)=1
((char *)&dv) == 0xbfbfc808
((char *)&dv) + 1 == 0xbfbfc809
((char *)&dv) + 2 == 0xbfbfc80a
C:\usr\c\> 

sample-003

Download : sample-003.c ( SJIS 版 )

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

int main ( void ) {
  int iv = 0x12345678;

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

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

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

  printf ( "((char *)&iv + 1) == %p\n", ((char *)&iv) + 1 );
  printf ( "*((char *)(&iv) + 1) == %x\n", *(((char *)(&iv)) + 1) );

  printf ( "((char *)&iv + 2) == %p\n", ((char *)&iv) + 2 );
  printf ( "*((char *)(&iv) + 2) == %x\n", *(((char *)(&iv)) + 2) );

  printf ( "((char *)&iv + 3) == %p\n", ((char *)&iv) + 3 );
  printf ( "*((char *)(&iv) + 3) == %x\n", *(((char *)(&iv)) + 3) );

  printf ( "\n" );

  /* */

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

  printf ( "*((char *)&iv) = 0\n" );
  *((char *)&iv) = 0;

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

  /* */

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

  printf ( "*((char *)&iv) = 0;\n" );
  *((char *)&iv) = 0;

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

  /* */

  return 0;
}
sample-003.c の実行結果
C:\usr\c\> sample-003
iv == 12345678
&iv == 0xbffe2bfc
*(&iv) == 12345678
(char *)&iv == 0xbffe2bfc
*((char *)(&iv)) == 78
((char *)&iv + 1) == 0xbffe2bfd
*((char *)(&iv) + 1) == 56
((char *)&iv + 2) == 0xbffe2bfe
*((char *)(&iv) + 2) == 34
((char *)&iv + 3) == 0xbffe2bff
*((char *)(&iv) + 3) == 12

iv == 12345678
*((char *)&iv) = 0
iv == 12345600
iv == 300
*((char *)&iv) = 0;
iv == 256
C:\usr\c\> 

sample-004

Download : sample-004.c ( SJIS 版 )

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

int main ( void ) {
  int iv;
  int *ip;

  ip = &iv;

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

  iv = 100;

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

  *ip = 200;

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

  return 0;
}
sample-004.c の実行結果
C:\usr\c\> sample-004
&iv == 0xbfd9967c
ip == 0xbfd9967c
iv == 100
*ip == 100
iv == 200
*ip == 200
C:\usr\c\> 

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 == 0xbf941cdc
iv == 5
sub:
	arg == 5
	&arg == 0xbf941cc0
	arg == 50
iv == 5
func:
	arg == 5
	&arg == 0xbf941cc0
	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\> 

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

本日の課題

課題20101119-01
次のプログラムの実行結果を予想し、その後入力し、実行結果と自分の予想を比較しなさい。
#include<stdio.h>

int main() {
	int va = 10;
	int *ip = &va;
	char *cp = (char *)&va;

	printf ( "ip=%p\n", ip );
	printf ( "ip + 1 = %p\n", ip + 1 );
	printf ( "cp=%p\n", cp );
	printf ( "cp + 1 = %p\n", cp + 1 );

	va = 300;
	printf ( "va = %d\n", va );

	*ip = 0;
	printf ( "va = %d\n", va );

	va = 300;
	printf ( "va = %d\n", va );

	*cp = 0;
	printf ( "va = %d\n", va );
}