C言語のポインタコーディング例 | 2024.07.08 |
整数型変数のポインタ |
#include <stdio.h>
int main(int argc, char *argv[])
{
int val;
int *valp1 = valp1 = &val;
int *valp2 = NULL;
*valp1 = 10;
printf("%d\n", val); // 10
val = 20;
printf("%d\n", *valp1); // 20
valp2 = valp1;
printf("%d\n", *valp2); // 20
return 0;
}
int main(int argc, char *argv[])
{
int val;
int *valp1 = valp1 = &val;
int *valp2 = NULL;
*valp1 = 10;
printf("%d\n", val); // 10
val = 20;
printf("%d\n", *valp1); // 20
valp2 = valp1;
printf("%d\n", *valp2); // 20
return 0;
}
C言語のポインタコーディング例 | 2024.07.08 |
配列の変数名をポインタとして参照する |
配列の[]を除いた名前の部分は、その配列の先頭位置を示すポインタである。
#include <stdio.h>
int main(int argc, char *argv[])
{
int arr[ 5 ] = { 1, 2, 3 };
printf("%d\n", *arr); // 1 arr[0]と同じ
printf("%d\n", *(arr + 2)); // 3 arr[2]と同じ
*(arr + 2) = 10; // arr[2]=10と同じ
printf("%d\n", arr[2]); // 10
return 0;
}
int main(int argc, char *argv[])
{
int arr[ 5 ] = { 1, 2, 3 };
printf("%d\n", *arr); // 1 arr[0]と同じ
printf("%d\n", *(arr + 2)); // 3 arr[2]と同じ
*(arr + 2) = 10; // arr[2]=10と同じ
printf("%d\n", arr[2]); // 10
return 0;
}
C言語のポインタコーディング例 | 2024.07.08 |
配列のポインタを別のポインタ変数で参照する |
ポインタ変数の加算や減算は、そのポインタのデータ型のサイズに従ってメモリ上の参照位置が計算される。short型ポインタの+1は+2バイト、long型ポインタの-1は-8バイトである。
#include <stdio.h>
int main(int argc, char *argv[])
{
int arr[ 5 ] = { 1, 2, 3 };
int *valp;
valp = arr; // valp = &arr[ 0 ]と同じ
printf("%d\n", *valp); // 1
valp = &arr[ 2 ]; // valp=(arr+2)と同じ
printf("%d\n", *valp); // 3
valp = arr + 2; // valp=&arr[2]と同じ
printf("%d\n", *valp); // 3
valp = arr;
printf("%d\n", *(valp + 2)); // 3 arr[2]と同じ
valp = arr;
printf("%d\n", valp[2]); // 3 ポインタ変数を配列のように参照
valp = arr;
*(valp + 2) = 10; // arr[2]=10と同じ
printf("%d\n", arr[2]); // 10
valp = arr;
valp++; // valpはarr[1]を指す
printf("%d\n", *valp); // 2
// arr = valp; // コンパイルエラー
return 0;
}
int main(int argc, char *argv[])
{
int arr[ 5 ] = { 1, 2, 3 };
int *valp;
valp = arr; // valp = &arr[ 0 ]と同じ
printf("%d\n", *valp); // 1
valp = &arr[ 2 ]; // valp=(arr+2)と同じ
printf("%d\n", *valp); // 3
valp = arr + 2; // valp=&arr[2]と同じ
printf("%d\n", *valp); // 3
valp = arr;
printf("%d\n", *(valp + 2)); // 3 arr[2]と同じ
valp = arr;
printf("%d\n", valp[2]); // 3 ポインタ変数を配列のように参照
valp = arr;
*(valp + 2) = 10; // arr[2]=10と同じ
printf("%d\n", arr[2]); // 10
valp = arr;
valp++; // valpはarr[1]を指す
printf("%d\n", *valp); // 2
// arr = valp; // コンパイルエラー
return 0;
}
C言語のポインタコーディング例 | 2024.07.08 |
多次元配列のポインタ |
#include <stdio.h>
int main(int argc, char *argv[])
{
int arr[2][3] = {{1, 2, 3}, {10, 20, 30}};
int *valp;
valp = &arr[ 1 ][ 2 ];
printf("%d\n", *valp); // 30
return 0;
}
int main(int argc, char *argv[])
{
int arr[2][3] = {{1, 2, 3}, {10, 20, 30}};
int *valp;
valp = &arr[ 1 ][ 2 ];
printf("%d\n", *valp); // 30
return 0;
}
C言語のポインタコーディング例 | 2024.07.08 |
配列の次元単位のポインタ |
#include <stdio.h>
int main(int argc, char *argv[])
{
int arr[2][3] = {{1, 2, 3}, {10, 20, 30 }};
int (*arrp)[3]; // int型[3]のポインタ
arrp = arr;
printf("%d\n", arrp[1][2]); // 30
printf("%d\n", *(arrp[1])); // 10 arrp[1]は{10,20,30}を指す
printf("%d\n", *(arrp[1] + 1)); // 20
printf("%d\n", *(*arrp + 2)); // 3
// *arrpはarrp[0]と同じで{1,2,3}を指す
printf("%d\n", *(*(arrp + 1) + 2)); // 30
// *(arrp+1)はarrp[1]と同じ
return 0;
}
int main(int argc, char *argv[])
{
int arr[2][3] = {{1, 2, 3}, {10, 20, 30 }};
int (*arrp)[3]; // int型[3]のポインタ
arrp = arr;
printf("%d\n", arrp[1][2]); // 30
printf("%d\n", *(arrp[1])); // 10 arrp[1]は{10,20,30}を指す
printf("%d\n", *(arrp[1] + 1)); // 20
printf("%d\n", *(*arrp + 2)); // 3
// *arrpはarrp[0]と同じで{1,2,3}を指す
printf("%d\n", *(*(arrp + 1) + 2)); // 30
// *(arrp+1)はarrp[1]と同じ
return 0;
}
C言語のポインタコーディング例 | 2024.07.08 |
ポインタ変数の配列 |
#include <stdio.h>
int main(int argc, char *argv[])
{
int arr[ 3 ] = { 1, 2, 3 };
int *parr[ 3 ];
parr[ 1 ] = &arr[ 2 ];
printf("%d\n", *parr[ 1 ]); // 3
return 0;
}
int main(int argc, char *argv[])
{
int arr[ 3 ] = { 1, 2, 3 };
int *parr[ 3 ];
parr[ 1 ] = &arr[ 2 ];
printf("%d\n", *parr[ 1 ]); // 3
return 0;
}
C言語のポインタコーディング例 | 2024.07.08 |
配列に文字列を初期化する |
char型配列に文字列リテラルで初期化するとき、文字列の長さが自動的に確保されるので配列サイズを省略できる。
文字列リテラルの配列の場合は、各要素の中で最大のサイズを指定する必要がある。
文字列リテラルの配列の場合は、各要素の中で最大のサイズを指定する必要がある。
#include <stdio.h>
int main(int argc, char *argv[])
{
char sarr1[] = "ABC";
char sarr2[][ 4 ] = { "ABC", "DEF" };
char *sarr3[] = { "ABC", "DEF" };
printf("%s\n", sarr1); // ABC
printf("%s\n", sarr2[ 1 ]); // DEF
printf("%s\n", sarr3[ 1 ]); // DEF
sarr3[0] = "XYZ";
printf("%s\n", sarr3[ 0 ]); // XYZ
return 0;
}
int main(int argc, char *argv[])
{
char sarr1[] = "ABC";
char sarr2[][ 4 ] = { "ABC", "DEF" };
char *sarr3[] = { "ABC", "DEF" };
printf("%s\n", sarr1); // ABC
printf("%s\n", sarr2[ 1 ]); // DEF
printf("%s\n", sarr3[ 1 ]); // DEF
sarr3[0] = "XYZ";
printf("%s\n", sarr3[ 0 ]); // XYZ
return 0;
}
C言語のポインタコーディング例 | 2024.07.08 |
ポインタによる文字列の参照 |
ポインタが参照する文字列リテラルへの代入はコンパイルエラーにはならないが、実行時にアクセス違反になる。
#include <stdio.h>
int main(int argc, char *argv[])
{
char *strp = "ABCDEFG";
printf("%s\n", strp); // ABCDEFG
printf("%s\n", strp + 1); // BCDEFG
printf("%c\n", strp[ 3 ]); // D
printf("%s\n", &strp[ 3 ]); // DEFG
printf("%c\n", *(strp + 2)); // C
strp += 2;
printf("%s\n", strp); // CDEFG
strp[ 1 ] = 'z'; // コンパイルエラーにはならないが異常終了する。
return 0;
}
int main(int argc, char *argv[])
{
char *strp = "ABCDEFG";
printf("%s\n", strp); // ABCDEFG
printf("%s\n", strp + 1); // BCDEFG
printf("%c\n", strp[ 3 ]); // D
printf("%s\n", &strp[ 3 ]); // DEFG
printf("%c\n", *(strp + 2)); // C
strp += 2;
printf("%s\n", strp); // CDEFG
strp[ 1 ] = 'z'; // コンパイルエラーにはならないが異常終了する。
return 0;
}
strpは文字列のリテラルを参照するポインタであり、char配列の実体が確保されているわけでない。
C言語のポインタコーディング例 | 2024.07.09 |
整数のポインタのポインタ |
#include <stdio.h>
int main(int argc, char *argv[])
{
int val = 10;
int *valp;
int **valpp;
valpp = &valp;
*valpp = &val;
printf("%d\n", *valp); // 10
printf("%d\n", **valpp); // 10
return 0;
}
int main(int argc, char *argv[])
{
int val = 10;
int *valp;
int **valpp;
valpp = &valp;
*valpp = &val;
printf("%d\n", *valp); // 10
printf("%d\n", **valpp); // 10
return 0;
}
valppはint型ポインタの場所を示すポインタである。
C言語のポインタコーディング例 | 2024.07.09 |
文字列のポインタのポインタ |
#include <stdio.h>
int main(int argc, char *argv[])
{
char s[] = "ABC";
char *strp;
char **strpp;
strpp = &strp;
*strpp = s;
printf("%s\n", strp); // ABC
return 0;
}
int main(int argc, char *argv[])
{
char s[] = "ABC";
char *strp;
char **strpp;
strpp = &strp;
*strpp = s;
printf("%s\n", strp); // ABC
return 0;
}
strppはchar型ポインタの場所を示すポインタである。
C言語のポインタコーディング例 | 2024.07.09 |
文字列のポインタ配列とポインタのポインタ |
#include <stdio.h>
int main(int argc, char *argv[])
{
char *sarr[] = { "ABC", "DEF", "GHI" };
char **strpp;
strpp = sarr;
printf("%s\n", strpp[ 2 ]); // GHI
return 0;
}
int main(int argc, char *argv[])
{
char *sarr[] = { "ABC", "DEF", "GHI" };
char **strpp;
strpp = sarr;
printf("%s\n", strpp[ 2 ]); // GHI
return 0;
}
sarrは文字列リテラルというう配列の先頭を示すポインタの配列なので、ポインタのポインタである。
C言語のポインタコーディング例 | 2024.07.09 |
構造体のポインタへの代入と参照 |
構造体のポインタからのメンバ参照で、「->」を使わないで書くならば、
(*(struct 構造体 *)構造体ポインタ).メンバ
#include <stdio.h>
int main(int argc, char *argv[])
{
struct config {
int enable;
char *name;
};
struct config cnf = { 1, "NAME" };
struct config *cnfp;
cnfp = &cnf;
printf("%d %s\n", cnfp->enable, cnfp->name);
// 1 NAME
printf("%d %s\n", (*(struct config *)cnfp).enable, (*(struct config *)cnfp).name);
// 1 NAME
return 0;
}
int main(int argc, char *argv[])
{
struct config {
int enable;
char *name;
};
struct config cnf = { 1, "NAME" };
struct config *cnfp;
cnfp = &cnf;
printf("%d %s\n", cnfp->enable, cnfp->name);
// 1 NAME
printf("%d %s\n", (*(struct config *)cnfp).enable, (*(struct config *)cnfp).name);
// 1 NAME
return 0;
}
C言語のポインタコーディング例 | 2024.07.09 |
構造体のポインタから配列・構造体メンバを参照する |
#include <stdio.h>
int main(int argc, char *argv[])
{
struct config {
int enable;
char *name;
int data[ 3 ];
struct attribute {
int flag;
double deg;
} attr;
} cnf = {
1, "NAME", { 10, 20, 30 }, { 0xaa, 25.67 }
};
struct config *cnfp = &cnf;
printf("enable=%d name=%s data2=%d attr.flag=%d attr.def=%f\n",
cnfp->enable,
cnfp->name,
cnfp->data[2],
cnfp->attr.flag, cnfp->attr.deg);
// enable=1 name=NAME data2=30 attr.flag=170 attr.def=25.670000
return 0;
}
int main(int argc, char *argv[])
{
struct config {
int enable;
char *name;
int data[ 3 ];
struct attribute {
int flag;
double deg;
} attr;
} cnf = {
1, "NAME", { 10, 20, 30 }, { 0xaa, 25.67 }
};
struct config *cnfp = &cnf;
printf("enable=%d name=%s data2=%d attr.flag=%d attr.def=%f\n",
cnfp->enable,
cnfp->name,
cnfp->data[2],
cnfp->attr.flag, cnfp->attr.deg);
// enable=1 name=NAME data2=30 attr.flag=170 attr.def=25.670000
return 0;
}
C言語のポインタコーディング例 | 2024.07.09 |
構造体のポインタから構造体の配列メンバを参照する |
#include <stdio.h>
int main(int argc, char *argv[])
{
struct config {
int enable;
char *name;
struct status {
int s;
} stat[ 3 ];
} cnf = { 1, "NAME", { 1, 2, 3 } };
struct config *cnfp = &cnf;
printf("%d\n", cnfp->stat[ 2 ].s); // 3
return 0;
}
int main(int argc, char *argv[])
{
struct config {
int enable;
char *name;
struct status {
int s;
} stat[ 3 ];
} cnf = { 1, "NAME", { 1, 2, 3 } };
struct config *cnfp = &cnf;
printf("%d\n", cnfp->stat[ 2 ].s); // 3
return 0;
}
C言語のポインタコーディング例 | 2024.07.09 |
構造体ポインタからポインタ変数メンバを参照する |
構造体のポインタからメンバを参照する「->」はポインタを参照する「*」より優先度が高い。
演算順位を明確にするならば、
演算順位を明確にするならば、
*(cnfp->valp)
#include <stdio.h>
int main(int argc, char *argv[])
{
struct config {
int enable;
char *name;
int *valp;
} cnf = { 1, "NAME", NULL };
struct config *cnfp = &cnf;;
int val = 100;
cnfp->valp = &val;
printf("%d\n", *cnfp->valp); // 100
return 0;
}
int main(int argc, char *argv[])
{
struct config {
int enable;
char *name;
int *valp;
} cnf = { 1, "NAME", NULL };
struct config *cnfp = &cnf;;
int val = 100;
cnfp->valp = &val;
printf("%d\n", *cnfp->valp); // 100
return 0;
}
C言語のポインタコーディング例 | 2024.07.09 |
構造体ポインタから構造体ポインタメンバを参照する |
#include <stdio.h>
int main(int argc, char *argv[])
{
struct attribute {
int flag;
double deg;
} attr = { 0xee, 34.56 };
struct config {
int enable;
char *name;
struct attribute *attrp;
} cnf = { 1, "NAME", NULL };
struct config *cnfp = &cnf;
cnfp->attrp = &attr;
printf("%02x %f\n",
cnfp->attrp->flag, cnfp->attrp->deg); // ee 34.560000
return 0;
}
int main(int argc, char *argv[])
{
struct attribute {
int flag;
double deg;
} attr = { 0xee, 34.56 };
struct config {
int enable;
char *name;
struct attribute *attrp;
} cnf = { 1, "NAME", NULL };
struct config *cnfp = &cnf;
cnfp->attrp = &attr;
printf("%02x %f\n",
cnfp->attrp->flag, cnfp->attrp->deg); // ee 34.560000
return 0;
}
C言語のポインタコーディング例 | 2024.07.09 |
構造体のポインタ配列を初期化する |
#include <stdio.h>
int main(int argc, char *argv[])
{
struct config {
int enable;
char *name;
};
struct config cnf1 = { 1, "AAAA" };
struct config cnf2 = { 2, "BBBB" };
struct config *cnfp[ 2 ] = { &cnf1, NULL };
cnfp[ 1 ] = &cnf2;
printf("%d %s\n",
cnfp[ 0 ]->enable, cnfp[ 1 ]->name); // 1 BBBB
return 0;
}
int main(int argc, char *argv[])
{
struct config {
int enable;
char *name;
};
struct config cnf1 = { 1, "AAAA" };
struct config cnf2 = { 2, "BBBB" };
struct config *cnfp[ 2 ] = { &cnf1, NULL };
cnfp[ 1 ] = &cnf2;
printf("%d %s\n",
cnfp[ 0 ]->enable, cnfp[ 1 ]->name); // 1 BBBB
return 0;
}
cnfp[0]~cnfp[2]は構造体ポインタなので各要素のメンバには「->」で参照する。
C言語のポインタコーディング例 | 2024.07.09 |
構造体を別の構造体型にキャスト |
構造体のデータを別の構造体型のポインタでキャストすることで、同一データを異なった構造体で参照できる。
#include <stdio.h>
int main(int argc, char *argv[])
{
struct data1 {
char cdata[ 2 ];
};
struct data2 {
short sdata;
};
struct data1 d1 = { 0x01, 0x02 };
struct data2 *d2;
d2 = (struct data2 *)&d1;
printf("%04x\n", d2->sdata); // 0201
return 0;
}
int main(int argc, char *argv[])
{
struct data1 {
char cdata[ 2 ];
};
struct data2 {
short sdata;
};
struct data1 d1 = { 0x01, 0x02 };
struct data2 *d2;
d2 = (struct data2 *)&d1;
printf("%04x\n", d2->sdata); // 0201
return 0;
}
C言語のポインタコーディング例 | 2024.07.09 |
参照渡しの関数の引数 |
ポインタ型の関数の引数は参照渡しとなり、関数の呼び出し元で引数に与えたデータを直接参照する。
参照渡しの引数には関数の中から代入して変更できる。関数の戻り値以外に引数で呼び出し側に処理結果を返すことができる(引数戻り値)。
constで宣言することで参照渡しのポインタ引数の代入を防止できる。
配列の引数は配列のポインタであり、s[]と*sは同義である。
参照渡しの引数には関数の中から代入して変更できる。関数の戻り値以外に引数で呼び出し側に処理結果を返すことができる(引数戻り値)。
constで宣言することで参照渡しのポインタ引数の代入を防止できる。
配列の引数は配列のポインタであり、s[]と*sは同義である。
#include <stdio.h>
#include <string.h>
void funcint(int *val)
{
printf("%d\n", *val); // 10
*val = 20;
}
void funcarr(const char s[])
{
printf("%s\n", s); // ABC
//strcpy(s, "DEF"); // コンパイルエラー
}
void funcstr(char *s)
{
printf("%s\n", s); // ABC
strcpy(s, "DEF");
}
int main(int argc, char *argv[])
{
int a = 10;
char str[] = "ABC";
funcint(&a);
printf("%d\n", a); // 20
funcarr(str);
funcstr(str);
printf("%s\n", str); // DEF
return 0;
}
#include <string.h>
void funcint(int *val)
{
printf("%d\n", *val); // 10
*val = 20;
}
void funcarr(const char s[])
{
printf("%s\n", s); // ABC
//strcpy(s, "DEF"); // コンパイルエラー
}
void funcstr(char *s)
{
printf("%s\n", s); // ABC
strcpy(s, "DEF");
}
int main(int argc, char *argv[])
{
int a = 10;
char str[] = "ABC";
funcint(&a);
printf("%d\n", a); // 20
funcarr(str);
funcstr(str);
printf("%s\n", str); // DEF
return 0;
}
C言語のポインタコーディング例 | 2024.07.09 |
構造体の引数参照渡し |
構造体のポインタを参照渡しで受ける関数は、引数の構造体のメンバを「->」で参照する。
一般に構造体を関数の引数に渡すときはポインタで参照渡しにする。そうでなければ構造体のコピーが行われる。
引数をconstで宣言しない場合、参照渡しの構造体は呼び出し元の内容を変更できる。
一般に構造体を関数の引数に渡すときはポインタで参照渡しにする。そうでなければ構造体のコピーが行われる。
引数をconstで宣言しない場合、参照渡しの構造体は呼び出し元の内容を変更できる。
#include <stdio.h>
struct attribute {
int flag;
double deg;
} attr;
void func(struct attribute *at)
{
printf("%d\n", at->flag); // 1
printf("%f\n", at->deg); // 2.340000
at->deg = 5.67;
}
int main(int argc, char *argv[])
{
struct attribute at = { 1, 2.34 };
func(&at);
printf("%f\n", at.deg); // 5.67000
return 0;
}
struct attribute {
int flag;
double deg;
} attr;
void func(struct attribute *at)
{
printf("%d\n", at->flag); // 1
printf("%f\n", at->deg); // 2.340000
at->deg = 5.67;
}
int main(int argc, char *argv[])
{
struct attribute at = { 1, 2.34 };
func(&at);
printf("%f\n", at.deg); // 5.67000
return 0;
}
C言語のポインタコーディング例 | 2024.07.09 |
関数の引数が多次元配列の参照 |
funcaa()の引数m[][2]の最初の配列サイズは省略、またはポインタにできる。
#include <stdio.h>
void funcaa(int m[][2])
{
printf("%d\n", m[0][0]); // 10
printf("%d\n", m[1][1]); // 200
}
void funcpa(int (*m)[2])
{
printf("%d\n", m[0][1]); // 20
printf("%d\n", m[1][0]); // 100
}
int main(int argc, char *argv[])
{
int mat[2][2] = { {10, 20}, {100, 200}};
funcaa(mat);
funcpa(mat);
return 0;
}
void funcaa(int m[][2])
{
printf("%d\n", m[0][0]); // 10
printf("%d\n", m[1][1]); // 200
}
void funcpa(int (*m)[2])
{
printf("%d\n", m[0][1]); // 20
printf("%d\n", m[1][0]); // 100
}
int main(int argc, char *argv[])
{
int mat[2][2] = { {10, 20}, {100, 200}};
funcaa(mat);
funcpa(mat);
return 0;
}
C言語のポインタコーディング例 | 2024.07.09 |
関数の引数がポインタ配列 |
ポインタの配列は、配列がポインタなのでポインタのポインタでもある。
#include <stdio.h>
void funcia(int *parr[])
{
printf("%d\n", *parr[0]); // 10
printf("%d\n", *parr[1]); // 20
}
void funcsa(char *sarr[])
{
printf("%s\n", sarr[0]); // ABC
printf("%s\n", sarr[1]); // DEF
}
void funcsp(char **spp)
{
printf("%s\n", spp[0]); // ABC
printf("%s\n", *(spp + 1)); // DEF
}
int main(int argc, char *argv[])
{
int mat[2] = { 10, 20 };
int *parr[ 2 ];
char *sarr[2] = { "ABC", "DEF" };
parr[ 0 ] = mat;
parr[ 1 ] = mat + 1;
funcia(parr);
funcsa(sarr);
funcsp(sarr);
return 0;
}
void funcia(int *parr[])
{
printf("%d\n", *parr[0]); // 10
printf("%d\n", *parr[1]); // 20
}
void funcsa(char *sarr[])
{
printf("%s\n", sarr[0]); // ABC
printf("%s\n", sarr[1]); // DEF
}
void funcsp(char **spp)
{
printf("%s\n", spp[0]); // ABC
printf("%s\n", *(spp + 1)); // DEF
}
int main(int argc, char *argv[])
{
int mat[2] = { 10, 20 };
int *parr[ 2 ];
char *sarr[2] = { "ABC", "DEF" };
parr[ 0 ] = mat;
parr[ 1 ] = mat + 1;
funcia(parr);
funcsa(sarr);
funcsp(sarr);
return 0;
}
C言語のポインタコーディング例 | 2024.07.09 |
引数戻り値にポインタを返す |
ポインタを返す関数の引数戻り値は、ポインタのポインタとして宣言する。
#include <stdio.h>
void func(int **retptr)
{
static int cons = 100;
*retptr = &cons;
}
int main(int argc, char *argv[])
{
int *valp;
func(&valp);
printf("%d\n", *valp); // 100
return 0;
}
void func(int **retptr)
{
static int cons = 100;
*retptr = &cons;
}
int main(int argc, char *argv[])
{
int *valp;
func(&valp);
printf("%d\n", *valp); // 100
return 0;
}
C言語のポインタコーディング例 | 2024.07.09 |
戻り値にポインタを返す関数 |
文字列リテラルは配列であり、配列を返すfuncra()は、
int []funcra()
のように定義できる。
#include <stdio.h>
int val = 10;
int *funcri()
{
return &val;
}
char *funcrs()
{
return "ABC";
}
int *funcra()
{
static int arr[ 2 ] = { 1, 2 };
return arr;
}
int main(int argc, char *argv[])
{
int *valp;
printf("%d\n", *funcri()); //10
printf("%s\n", funcrs()); //ABC
valp = funcra();
printf("%d\n", valp[1]); // 2
return 0;
}
int val = 10;
int *funcri()
{
return &val;
}
char *funcrs()
{
return "ABC";
}
int *funcra()
{
static int arr[ 2 ] = { 1, 2 };
return arr;
}
int main(int argc, char *argv[])
{
int *valp;
printf("%d\n", *funcri()); //10
printf("%s\n", funcrs()); //ABC
valp = funcra();
printf("%d\n", valp[1]); // 2
return 0;
}
C言語のポインタコーディング例 | 2024.07.09 |
構造体のポインタを返す関数 |
#include <stdio.h>
struct attribute {
int flag;
double deg;
} attr = { 1, 2.34 };
struct attribute *func()
{
return &attr;
}
int main(int argc, char *argv[])
{
struct attribute *attp;
attp = func();
printf("%d\n", attp->flag); //1
printf("%f\n", attp->deg); //2.340000
return 0;
}
struct attribute {
int flag;
double deg;
} attr = { 1, 2.34 };
struct attribute *func()
{
return &attr;
}
int main(int argc, char *argv[])
{
struct attribute *attp;
attp = func();
printf("%d\n", attp->flag); //1
printf("%f\n", attp->deg); //2.340000
return 0;
}
C言語のポインタコーディング例 | 2024.07.09 |
voidポインタからポインタ型のキャスト |
voidポインタとして宣言された変数は型が不明なので、参照するときは何の型として参照するかを明示的に型キャストする必要がある。
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
void *vp;
short val = 0x1020;
char *cvp;
vp = &val;
cvp = (char *)vp;
printf("%d\n", *(short *)vp); //4128
printf("%02x\n", *cvp); //20
printf("%02x\n", *(cvp + 1)); //10
return 0;
}
#include <stdlib.h>
int main(int argc, char *argv[])
{
void *vp;
short val = 0x1020;
char *cvp;
vp = &val;
cvp = (char *)vp;
printf("%d\n", *(short *)vp); //4128
printf("%02x\n", *cvp); //20
printf("%02x\n", *(cvp + 1)); //10
return 0;
}
C言語のポインタコーディング例 | 2024.07.09 |
配列をvoidポインタのキャストにより別の型で参照する |
#include <stdio.h>
int main(int argc, char *argv[])
{
char carr[ 4 ] = { 0x01, 0x02, 0x03 };
void *vp;
vp = carr;
printf("%04x\n", *(short *)vp); // 0201
return 0;
}
int main(int argc, char *argv[])
{
char carr[ 4 ] = { 0x01, 0x02, 0x03 };
void *vp;
vp = carr;
printf("%04x\n", *(short *)vp); // 0201
return 0;
}
C言語のポインタコーディング例 | 2024.07.09 |
voidポインタで異なる構造体型にキャスト |
構造体ポインタをvoidポインタから別の構造体のポインタにキャストして、異なる構造体型として参照する。
#include <stdio.h>
struct carr {
char c[ 4 ];
int len;
};
int main(int argc, char *argv[])
{
struct sarr {
short s[ 2 ];
int len;
};
void *vp;
struct carr ca
= { { 0x01, 0x02, 0x03, 0x04 }, 4 };
vp = &ca;
printf("%04x\n", ((struct sarr *)vp)->s[ 0 ]); // 0201
((struct sarr *)vp)->len = 2;
printf("%d\n", ca.len); // 2
return 0;
}
struct carr {
char c[ 4 ];
int len;
};
int main(int argc, char *argv[])
{
struct sarr {
short s[ 2 ];
int len;
};
void *vp;
struct carr ca
= { { 0x01, 0x02, 0x03, 0x04 }, 4 };
vp = &ca;
printf("%04x\n", ((struct sarr *)vp)->s[ 0 ]); // 0201
((struct sarr *)vp)->len = 2;
printf("%d\n", ca.len); // 2
return 0;
}
C言語のポインタコーディング例 | 2024.07.09 |
関数ポインタ |
関数名は関数へのポインタである。
関数square()のポインタを、関数ポインタfuncに代入してポインタの参照で関数を呼び出している。
関数square()のポインタを、関数ポインタfuncに代入してポインタの参照で関数を呼び出している。
#include <stdio.h>
int square(short a)
{
return a*a;
}
int main(int argc, char *argv[])
{
int (*func)(short) = square;
printf("10*10 = %d\n", (*func)( 10 )); //10*10 = 100
return 0;
}
int square(short a)
{
return a*a;
}
int main(int argc, char *argv[])
{
int (*func)(short) = square;
printf("10*10 = %d\n", (*func)( 10 )); //10*10 = 100
return 0;
}
C言語のポインタコーディング例 | 2024.07.09 |
関数ポインタに関数を切り替えて代入して呼び出す |
#include <stdio.h>
#include <stdlib.h>
int Abs(int a)
{
if (a < 0) {
return (a * -1);
}
return a * a;
}
int main(int argc, char *argv[])
{
int (*func)(int);
func = abs; //標準ライブラリ(stdlib)の関数
printf("abs -10 .. %d\n", (*func)( -10 )); // abs -10 .. 10
func = Abs;
printf("Abs -10 .. %d\n", (*func)( -10 )); // Abs -10 .. 10
return 0;
}
#include <stdlib.h>
int Abs(int a)
{
if (a < 0) {
return (a * -1);
}
return a * a;
}
int main(int argc, char *argv[])
{
int (*func)(int);
func = abs; //標準ライブラリ(stdlib)の関数
printf("abs -10 .. %d\n", (*func)( -10 )); // abs -10 .. 10
func = Abs;
printf("Abs -10 .. %d\n", (*func)( -10 )); // Abs -10 .. 10
return 0;
}
C言語のポインタコーディング例 | 2024.07.09 |
引数の関数ポインタを関数内で呼び出す(コールバック) |
コールバックにより関数側で一部の処理を外部に委ねることができる。コールバックの関数はポインタ引数で与える以外に、構造体に関数ポインタを含めて渡すなどの方法がある。
#include <stdio.h>
#include <stdlib.h>
void show(int (*func)(const char *), char *s)
{
(*func)(s); // by puts()
}
int main(int argc, char *argv[])
{
show(puts, "by puts()");
return 0;
}
#include <stdlib.h>
void show(int (*func)(const char *), char *s)
{
(*func)(s); // by puts()
}
int main(int argc, char *argv[])
{
show(puts, "by puts()");
return 0;
}
C言語のポインタコーディング例 | 2024.07.09 |
関数ポインタの配列 |
#include <stdio.h>
int square(int a)
{
return a*a;
}
int cube(int a)
{
return a*a*a;
}
int main(int argc, char *argv[])
{
int (*func[ 2 ])(int);
func[ 0 ] = square;
func[ 1 ] = cube;
printf("square 10*10=%d\n",(*func[0])(10));
// quare 10*10=100
printf("cube 10*10*10=%d\n", (*func[1])(10));
// cube 10*10*10=1000
return 0;
}
int square(int a)
{
return a*a;
}
int cube(int a)
{
return a*a*a;
}
int main(int argc, char *argv[])
{
int (*func[ 2 ])(int);
func[ 0 ] = square;
func[ 1 ] = cube;
printf("square 10*10=%d\n",(*func[0])(10));
// quare 10*10=100
printf("cube 10*10*10=%d\n", (*func[1])(10));
// cube 10*10*10=1000
return 0;
}