C语言学习之七——指针_2_数组

!!!注意:因为简书的显示格式缘故,所以“ * ”显示会出现问题,可能有些星号由于疏忽未改动格式,造成没有显示,请多多包含,如有错误,请留言或联系本人更正,谢谢!

  1. 指针和数组
    1.1通过指针得到整个数组:由于数组是由各个具有相同性质的数组元素按照一定顺序排布的集合,而每个数组元素都占一定的内存空间,且由数据结构知识可知,数组元素在内存中的排布是连续的。因此,只要知道数组的首地址,那么整个数组就可以被知晓。由此可知,只需要将指针指向数组首地址,就可以按照地址顺序知道整个数组。

    1.2数组元素的指针:即为指向数组元素的指针(换句话说,就是数组元素的地址)。见例1

//例1,定义一个指向数组元素的指针变量
int a[5] = {1,2,3,4,5}; //定义数组a
int *p; //定义指针变量p
p = &a[2]; //将数组a的第三个元素的地址赋给p(即p中存储数组a的第三个元素的地址)

引用数组元素的方法:1)下标法,如a[i]; 2)指针法,如(a+i)或(p+ i)。(注:i为第i+1个元素)

//例2
/#include<stdio.h>
void main()
{
int a[5] = {1,2,3,4,5};
int *p, i;
p = a; //这里a是数组名,p是指向数组元素的指针变量,注意:数组名即“翻译成数组的第一个元素的地址!因此将数组的第一个元素的地址赋给p,后面的数组元素就可以通过地址+1得到。
//p = &a[0]; //这也是同样道理,因为a[0]的地址即为数组的首地址。
for(i = 0; i < 5; i++)printf("%d ", *(p + i));
printf("\n");
}

例题:假设有一个a数组,整型,有10个元素。要输出各元素的值有三种方法,见例3.
(1) 下标法
(2) 通过数组名计算数组元素地址,找出元素的
值。
(3) 用指针变量指向数组元素。

//例3
/#include<stdio.h>
void main()
{
int a[5] = {1,2,3,4,5};
int *p, i;
for(i = 0; i < 5; i++)printf("第一种方法:%d ", a[i]);
printf("\n");
for(i = 0; i < 5; i++)printf("第二种方法:%d ", *(a + i));
printf("\n");
p = a; //p = &a[0]也是等价的
for(i = 0; i < 5; i++)printf("第三种方法:%d ", *(p + i));
printf("\n");
}
//输出:第一种方法:1 第一种方法:2 第一种方法:3 第一种方法:4 第一种方法:5
第二种方法:1 第二种方法:2 第二种方法:3 第二种方法:4 第二种方法:5
第三种方法:1 第三种方法:2 第三种方法:3 第三种方法:4 第三种方法:5

  1. 用数组名作函数参数
    2.1 f(int arr[], int n) 与 f(int *arr, int n),这两个是等价的,因为在编译时编译器将arr按照指针变量处理(因为,arr中存储的是数组的首地址,在调用函数f的时候,取的是数组arr 的首地址然后进行下面一系列运算)(注:C语言调用函数时虚实结合的方法都是采用“值传递”方式,当用变量名作为函数参数时传递的是变量的值,当用数组名作为函数参数时,由于数组名代表的是数组首元素地址,因此传递的值是地址,所以要求形参为指针变量。)
    见例4,例5

//例4
/#include<stdio.h>
void main()
{
int a[5] = {1, 2, 3, 4, 5};
int *p, f(int arr[], int n);
f(a, 5);
printf("///////////////////////////////////////////////////\n");
p = a;
f(p, 5);
}

int f(int arr[], int n)
{
int i;
for (i= 0; i < n; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
//输出:
1 2 3 4 5
///////////////////////////////////////////////////
1 2 3 4 5

//例5
/#include<stdio.h>
void main()
{
int a[5] = {1, 2, 3, 4, 5};
int *p, f(int *arr, int n);
f(a, 5);
printf("///////////////////////////////////////////////////\n");
p = a;
f(p, 5);
}

int f(int *arr, int n)
{
int i;
for (i= 0; i < n; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
//输出:
1 2 3 4 5
///////////////////////////////////////////////////
1 2 3 4 5

例题:将数组a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}中10个整数按相反顺序存放
方法一,用将数组a的数组反向插入到另一个空数组中:

/#include<stdio.h>
void main()
{
int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, b[10];
int reverse(int a[], int b[]);
int i;
reverse(a, b);
for (i = 0; i <= 9; i++)
{
printf("%d ", b[i]);
}
printf("\n");
}

int reverse(int a[], int b[])
{
int i, j;
for (i = 0, j = 9; i <= 9 && j >= 0; i++, j-- )
{
b[j] = a[i];
}
return b[0];
}
//输出:10 9 8 7 6 5 4 3 2 1

方法二,将数组的末元素地址赋给一个数组变量,然后依照地址数-1的顺序得到反向的数组元素,并依次存入另一个空数组中。

/#include<stdio.h>
void main()
{
int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, b[10];
int *p, i;
void reverse(int *p1, int b[]);
p = &a[9];
reverse(p, b);
for (i = 0; i <= 9; i++)
{
printf("%d ", b[i]);
}
printf("\n");
}

void reverse(int *p1, int b[])
{
int i;
for (i = 0; i <= 9; i++)
{
b[i] = *(p1 - i);
}
}
//输出:10 9 8 7 6 5 4 3 2 1

2.2归纳:如果有一个实参数组,想在函数中调用这个实参数组,实参与形参的对应关系有以下4种情况:
1)形参和实参都用数组名,如:

void main()
{
int a[10];
void f(int x[],int n) //函数声明
f(a,10); //函数调用,这里传入的参数都是实参
}

void f(int x[],int n) //函数定义,这里定义的参数都是实参
{
……
}

2)实参用数组名,形参用指针变量。如:

void main()
{
int a[10];
void f (int *a, int n);
f (a, 10);
}

void f (int *a, int n)
{
…...
}

3)实参形参都用指针变量。例如:

void main()
{
int a[10], *p;
p = a;
void f (int *x, int n);
f (p , 10);
}

void f (int *x, int n)
{
......
}

4)实参为指针变量,形参为数组名。如:

void main()
{
int a[10], *p;
p = a;
f(p,10);
}

f (int x[], int n)
{
............
}

例题:对数组中10个整数按由大到小顺序排序
/#include<stdio.h>
void main()
{
int a[10] = {99, 88, 11, 77, 56, 35, 110, 201, 5, 33};
int sort(int a[], int n);
int i;
sort(a, 10);
for(i = 0; i < 10; i++)printf("%d ", a[i]);
printf("\n");
}

int sort(int a[], int n)
{
int i, j, temp;
for(i = 0; i < (n - 1); i++)
for(j = i; j < n; j++)
{
if (a[i] < a[j])
{
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
//输出:201 110 99 88 77 56 35 33 11 5

  1. 多维数组与指针
    3.1设有一个二位数组a[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}},且其首地址为2000,则其内存中的存储方式为:


    二维数组在内存中的存储方式

    指针及下标表示数组的方式

    3.2指向对维数组元素的指针变量:
    把二维数组a分解为一维数组a[0],a[1],a[2]之后,设p为指向二维数组的指针变量。可定义为:int ( * p)[4] (它表示p是一个指针变量,它指向包含4个元素的一维数组。若指向第一个一维数组a[0],其值等于a,a[0],或&a[0][0]等。而p+i则指向一维数组a[i]。)
    由此我们可以得出 * (p+i)+j是二维数组i行j 列的元素的地址,而 * (*(p+i)+j)则是i行j列元素的值。

    二维数组指针变量的一般定义形式:类型说明符(指针变量名)[长度] (“类型说明符”为所指数组的数据类型。“”表示其后的变量是指针类型。“长度”表示二维数组分解为多个一维数组时,一维数组的长度,也就是二维数组的列数。)见例6

//例6
/#include <stdio.h>
void main()
{
int a[3][4] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
int (* p)[4];
int i, j;
p = a;
for( i=0; i < 3; i++)
{
for( j=0; j < 4; j++)
{
printf("%2d ", * ( * (p+i)+j)); /这里的i就表示 行,j表示列,+i的时候即根据 ( * p)[4] 中4列的原则,从数组的首地址跳过4 * i个数组元素存储空间,到i行;+j的时候即从i行的起始位置算起跳过j个数组元素存储空间到j列,到此即为要找的数组元素/

}
printf("\n");
}
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容