http://murakan.cocolog-nifty.com/blog/2011/08/cc-b731.html
http://www.aso.ecei.tohoku.ac.jp/~shun/multi_dim.html
1. 用指针代替数组好处
1-1. 节省内存使用
数组每行元素要保留最大元素的长度
而指针只保留每个元素实际长度
1-2. 作为函数参数, 在函数中访问并可以修改 (地址传递)
1-3. 将数组定义为字符串
1-4. 在结构体中使用
------------------------------------------------------------
2. 字符串与指针的关系
2-1. 字符串可以定义为字符数组 char str[], 也可以定义为字符指针 char *str, 相当于指针数组, str 中存储字符串第一个字符的地址
#include<stdio.h>
main()
{
char *c = "12345"; /* 正确 */
int *i = "12345"; /* 错误, 只能定义字符串 */
char *c; c ="12345"; /* 初始化错误 */
printf("%s",c);
}
2-2. 将字符串定义为指针数组, 可以直接进行指针运算
#include<stdio.h>
main()
{
char *str ="12345";
for(;*str!='\0';str+=1)
printf("%s\n",str); /* 直接将指针变量转换为值 */
}
------------------------------------------------------------
3. 将数组传递给函数
3-1. 数组变量的传递
#include<stdio.h>
main()
{
int i[]={1,2};
int ans;
ans=func(i);
}
int func(int x[])
{
return (x[0] * x[1]);
}
3-2. 数组指针的传递
#include<stdio.h>
main()
{
int i[]={1,2};
int ans;
ans=func(i); /* i 代表数组 i[] 起始地址 */
}
int func(int *x)
{
return (*x * *(x+1));
}
------------------------------------------------------------
4. 一维数组与指针的关系
#include<stdio.h>
main()
{
int i,arr[] = {0,1,2,3,4,5,6,7,8,9};
int *point;
point = arr;
for(i=0;i<10;i++){
printf("&arr[%d] = %p arr[%d] = %d ",i,&arr[i],i,arr[i]);
printf("point+%d = %p *(point+%d) = %d\n",i,point+i,i,*(point+i));
}
}
point+i = point (arr的开始地址) + size (指针类型) * i
地址 : &arr[i] = point+i
元素 : arr[i] = *(point+i)
------------------------------------------------------------
5. 二维数组与指针
5-1.
#include<stdio.h>
main()
{
int matrix[2][3] = {{1,2,3},{4,5,6}};
printf("matrix[0][0] = %d\n",**matrix );
printf("matrix[0][1] = %d\n",*(*matrix+1) );
printf("matrix[0][2] = %d\n",*(*matrix+2) );
printf("matrix[1][0] = %d\n",**(matrix+1) );
printf("matrix[1][1] = %d\n",*(*(matrix+1)+1));
printf("matrix[1][2] = %d\n",*(*(matrix+1)+2));
printf(" &matrix[0][0] = %d\n",&matrix[0][0]);
printf(" &matrix = %d\n",&matrix);
printf(" matrix = %d\n",matrix);
printf(" *matrix = %d\n",*matrix);
printf("**matrix = %d\n",**matrix);
printf("&matrix[0][0]+1 = %d\n",&matrix[0][0]+1);
printf("&matrix+1 = %d\n",&matrix+1);
printf(" matrix+1 = %d\n",matrix+1);
printf("*matrix+1 = %d\n",*matrix+1);
}
指针p, 不能访问 matrix
int **point;
point=matrix;
&matrix : 行列开始处的地址
matrix : 第一行开头的地址
*matrix : 第一列开头的地址
**matrix : 元素的值
此时, &matrix = matrix = *matrix
指针 + 1 之后的情况
&matrix+1 : 行列结尾的下一个地址(+24)
matrix+1 : 下一行的开始地址(+12)
*matrix+1 : 下一个元素的地址(+4)
5-2. 二维数组的指针访问
5-2-1. 数组的指针 (适合访问处理)
#include <stdio.h>
int main()
{
int data[][3] = {{1, 2, 3}, {4, 5, 6}};
int (*dPtr)[3] = data;
printf("data[0][0] = %d\n", dPtr[0][0]);
printf("data[0][1] = %d\n", dPtr[0][1]);
printf("data[0][2] = %d\n", dPtr[0][2]);
printf("data[1][0] = %d\n", dPtr[1][0]);
printf("data[1][1] = %d\n", dPtr[1][1]);
printf("data[1][2] = %d\n", dPtr[1][2]);
return 0;
}
内存形态如下:
dPtr data[2][3]
+-----+ +-----------+
|&data|----->| 1 | 2 | 3 |
+-----+ |-----------|
| 4 | 5 | 6 |
+-----------+
5-2-2. 指针数组 (适合排序处理)
#include<stdio.h>
int main(){
int matrix[2][3]={ {1, 2, 3}, {4, 5, 6} };
int *point[2];
point[0]=matrix[0];
point[1]=matrix[1];
printf("matrix[0][0] = %d\n",point[0][0]);
printf("matrix[0][1] = %d\n",point[0][1]);
printf("matrix[0][2] = %d\n",point[0][2]);
printf("matrix[1][0] = %d\n",point[1][0]);
printf("matrix[1][1] = %d\n",point[1][1]);
printf("matrix[1][2] = %d\n",point[1][2]);
return 0;
}
内存形态:
point[2] matrix[2][3]
+-------+ +-----------+
|data[0]|----->| 1 | 2 | 3 |
+-------+ |-----------|
|data[1]|----->| 4 | 5 | 6 |
+-------+ +-----------+
5-3. 二维数组函数参数传递
void fa (int a[][5]);
main ()
{
int a[3][5] = { ... };
fa(a); /* 指针传递 */
}
void fa(int a[][5]) /* 5 必须 */
{ ... }
------------------------------------------------------------
6. 指针的指针
#include<stdio.h>
main()
{
int i=10;
int *p;
int **point;
p=&i;
point=&p;
printf(" i = %d\n",i);
printf(" *p = %d\n",*p);
printf("**point = %d\n",**point);
printf(" &i = %p\n",&i);
printf(" p = %p\n",p);
printf(" *point = %p\n",*point);
printf(" &p = %p\n",&p);
printf(" point = %p\n",point);
printf(" &point = %p\n",&point);
}
|---------|------|----------------|-------------|
|地址 |变量 |值 |访问 |
|0064FE00 |i |10(10进制) |i,*p,**point |
|0064FDFC |p |64FE00(16进制) |&i,p,*point |
|0064FDF8 |point |64FDFC(16进制) |&p,point |
|---------|------|----------------|-------------|
------------------------------------------------------------
7. 指针函数 (返回值是指针的函数)
#include <stdio.h>
char *string_func(int n);
int *int_func(int);
main()
{
int i;
for ( i=1;i<=3;i++){
printf("String No.%d %s\n",i,string_func(i));
}
printf(" int_func(30) value = %d\n",int_func(30));
printf("*int_func(30) value = %d\n",*int_func(30));
return 0;
}
char *string_func(int n)
{
static char *string[] = {
"",
"C-Production",
"Official HomePage",
"Spring Version"
};
return string[n];
}
int *int_func(int n)
{
int *integer;
integer = &n;
return integer;
}
结果
String No.1 C-Production
String No.2 Official HomePage
String No.3 Spring Version
int_func(30) value = 6618624
*int_func(30) value = 30
------------------------------------------------------------
8 函数的指针
8-1 用函数指针调用函数
#include <stdio.h>
void func(int);
int main()
{
void (*P_func)(int);
P_func = func;
(*P_func)(1);
return 0;
}
void func(int i)
{
printf("%d",i);
return;
}
8-2 函数指针与数组结合
#include<stdio.h>
int and(int x,int y);
int or(int x,int y);
void main()
{
int (*p_func[2])(int x,int y);
int i,j,k;
p_func[0] = and;
p_func[1] = or;
printf("x y AND OR\n");
for(i=0;i<2;i++){
for(j=0;j<2;j++){
printf("%d %d ",i,j);
for(k=0;k<2;k++){
printf(" %d ",(*p_func[k])(i,j));
}
printf("\n");
}
}
}
int and(int x, int y)
{
return x&&y;
}
int or(int x, int y)
{
return x||y;
}
結果
x y AND OR
0 0 0 0
0 1 0 1
1 0 0 1
1 1 1 1
------------------------------------------------------------
9. 指针函数的指针 (指向返回值为指针的函数的指针)
#include <stdio.h>
char *string_func(int n);
int main()
{
int i;
char *(*P_func)(int);
P_func = string_func;
for ( i=1;i<=3;i++){
printf("String No.%d %s\n",i,(*P_func)(i));
}
return 0;
}
char *string_func(int n)
{
static char *string[] = {
"",
"C-Production",
"Official HomePage",
"Spring Version"
};
return string[n];
}
0 件のコメント:
コメントを投稿