• 问题总会出现,不过解决问题的方法也会出现!!!

C语言基础学习笔记16

学习笔记 小雨 564次浏览 已收录 0个评论

—— ——-

数组指针的概念及定义

  1. 数组指针

数组元素指针

一个变量有地址,一个数组包含若干个元素,每个数组元素都有相应的地址。

指针变量可以指向数组元素(把某一元素的地址放到一个指针变量中)

所谓数组元素的指针就是数组元素的地址

可以用一个指针变量指向一个数组元素
C语言基础学习笔记16

注意:

  1. 数组名a不代表整个数组,只代表数组首元素的地址

“p=a;”的作用是“把数组的首元素地址赋给指针变量p”,而不是“把数组a各元素的值赋给p”

 

数组指针初始化和使用方法

  1. 使用指针引用数组元素(使用p++这种方式,可以使指针偏移)

在指针指向素组元素时,允许以下运算:

加一个整数(用+或+=),如p+=1;比如:int *p=&a;p=0x00;当p=p+1;此时p=0x04;

减一个整数(用-或-=),如 p-=1;

自加运算,如p++,++p;

自减运算,如p–,–p;

两个指针相减,如p1-p2(只有p1和p2都指向同一数组中的元素时才有意义)

如果指针变量p已指向数组中的一个元素,则p+1指向同一数组中的下一个元素,

P-1指向同一数组中的上一个元素

例:float a[10],float *p=a;  //float类型占4个字节

假设a[0]的地址为0x2000,则

P的值为2000;

P+1的值为2004;

P-1的值为 1996;

比如:int a[]={1,2,3,4}; int *p=a; p=p+1;实际可以理解为:p+1*sizeof(int);

注意:

  1. 如果p的初值为&a[0],则p+i和a+i就是数组元素a[i]的地址,或者说,他们指向a数组序号为i的元素。(a作为数组名,其实只是一个地址,所以a==p)

C语言基础学习笔记16

数组指针:指向数组元素的指针

数组指针的作用:使用数组指针间接访问数组的元素

数组指针的定义:int *p;

数组指针的初始化:int a[]={1,2,3,4};  int *p=a;

数组指针,定义了一个指针变量p赋值数组的首地址(第一个元素的)

p就指向了数组的第一个元素

int *p=&a[0];这句话就等价于int *p=a;

 

用数组指针遍历数组

for(int i=0;i<4;i++){

printf(“%dt”,*p++);

}

误区:数组名 a 是一个常量,而自增等操作都是相对于变量而言的

printf(“*a++ =%dn”,*a++);//这一步将无法编译

printf(“*a =%dn”,*a);

结论:

引用一个数组元素可用下面两种方法:

  1. 下标法,如a[i]形式
  2. 指针法,如*(a+i)或*(p+i),p一直指向数组首地址,等同a
  3. A是常量(a++错误),p是变量(p++正确)

 

C语言基础学习笔记16

指针法遍历数组

//  C语言-指针法遍历数组

#include <stdio.h>

int main(int argc, const char * argv[]) {

int array[]={1,2,3,4,5,6,7,8,9,10};

for (int i=0; i<10; i++) {

printf(“%dt”,*(array+i));

}

printf(“n”);

int *p=array;

for (int i=0; i<10; i++) {

printf(“%dt”,*(p+i));

}

printf(“n”);

printf(“Hello, World!n”);

return 0;

}

 

 

应用:逆序数组

用指针将数组a中n个整数按相反顺序存放

解题思路:将a[0]与a[n-1]对换,···将a[4]与[5]对换。

注意:a[i]=*(a+i);

C语言基础学习笔记16 C语言基础学习笔记16

C语言基础学习笔记16

代码:

#include <stdio.h>

void niXuArray(int a[],int len){

int i=0,j=len-1;

int temp;

while (i<j) {

//交换a[i]和a[j]

temp=*(a+j);

*(a+j)=*(a+i);

*(a+i)=temp;

//修改下标

i++,j–;

}

}

 

int main(int argc, const char * argv[]) {

int array[10]={1,2,3,4,5,6,7,8,9,10};

for (int i=0; i<10; i++) {

printf(“%dt”,*(array+i));

}

printf(“n”);

niXuArray(array, 10);

for (int i=0; i<10; i++) {

printf(“%dt”,*(array+i));

}

return 0;

}

 

一维指针数组

  1. 一维指针数组

一个数组的元素值为指针则是指针数组。指针数组是一组有序的指针的结合。指针数组的所有元素都必须是具有相同存储类型和指向相同数据类型的指针变量。

指针数组说明的一般形式为:

类型说明符 *数组名[数组长度]

其中类型说明符为指针值所指向的变量的类型。例如:

int *pa[3];//只能存放3个int类型变量的指针

表示pa是一个指针数组,它有三个数组元素,每个元素值都是一个指针,指向整形变量。

指针数组的使用:

int a=3,b=4,d=5;

int *pa[3]={&a,&b,&c};

 

#include <stdio.h>

int main(int argc, const char * argv[]) {

int a=1,b=2,c=3;

int *array[]={&a,&b,&c};

//打印指针数组的第一个元素

printf(“&a      = %pn”,&a);

printf(“array[0]= %pn”,array[0]);

//打印指针数组的首地址

printf(“array     = %pn”,array);

printf(“&array[0] = %pn”,&array[0]);

//访问a

printf(“*(&a) =%dn”,*(&a));

printf(“*array[0] =%dn”,*array[0]);

//使用数组名来访问a

//数组名 array

//**array

printf(“**array   =%d”,**array);

return 0;

}

 

指针变量之间的算术运算和关系运算

只有指向同一组的两个指针变量之间开能进行运算,否则运算毫无意义。

  1. 两指针变量减法运算

两指针变量相减之差是两个指针所指元素之间相差的元素个数

实际上是两个指针(地址)相减之差再除以该元素的长度(字节数)

  1. 指针之间的算术运算

(pointer2地址值-pointer地址值)/sizeof(所指向数据类型)

C语言基础学习笔记16

(1)0x0006-0x0003=3(意义不大)

(2)常见的用法:两个指针都指向同一个数组

I:判断两个指针变量指向的元素是否连续

II:判断两个指针变量之间相隔几个元素

C语言基础学习笔记16

注意:两个指针之间没有加法运算

  1. 两个指针之间的关系运算

//p1>0

//1      表示p1在高位

//0      p在高位或者他们指向了同一个位置

#include <stdio.h>

int main(int argc, const char * argv[]) {

int array[]={1,2,3,4,5,6};

int *p=array;       //p     指向了数组的第1个元素

int *p1=&array[2];  //p1    指向了数组的第3个元素

//    1.  指针之间的算术运算

//地址差值(p1-p)*sizeof(int)

printf(“p1 – p =%ldn”,p1 – p);

printf(“p – p1 =%ldn”,p – p1);

//    注意:两个指针之间没有加法运算

//如果两个指针变量指向同一个元素,那么他们相减的结果是0

//判断两个指针变量是否相邻(连续),他们相减的结果是1的绝对值

//    2.  两个指针之间的关系运算

//p1>0

//1    表示p1在高位

//0    p在高位或者他们指向了同一个位置

printf(“p1 > p =%dn”,p1>p);

return 0;

}

 

7-用数组名访问二维数组

C语言基础学习笔记16

a代表第0行首地址, a+1代表第1行首地址 a+2代表第2行首地址

a+i代表第i行的首地址(按行变化)

C语言基础学习笔记16

a[0]代表a[0][0]的地址

a[0]+1代表a[0][1]的地址

a[0]+2代表a[0][2]的地址

a[0]+3代表a[0][3]的地址

C语言基础学习笔记16

C语言基础学习笔记16

C语言基础学习笔记16

8-普通指针访问二维数组

指向二维数组元素的指针变量

#include <stdio.h>

int main(int argc, const char * argv[]) {

int arr[4][3]={12,45,62,21,54,32,85,2,6,48,57,98};

int *p=arr;//会有提示,但依然是能够遍历的

for (int i=0; i<12; i++) {

printf(“%dt”,*(p+i));

}

return 0;

}

9-二维数组指针定义、初始化

在上面的说明中我们已经知道,二维数组是指向型的,它不能对如下说明的指针变量p直接赋值int arr[4][3]={12,45,62,21,54,32,85,2,6,48,57,98};,*p;

原因是p与a的性质不同,或者说二者不是同一级指针。C语言可以通过定义行数组指针的方法,使得一个指针变量与二维数组名具有相同的性质。

二维数组指针变量说明

一般形式为:

数组类型(*指针变量)[二维数组列];

其中“类型说明符”为所指数组数据类型。“*”表示其后的变量是指针类型。

如要将二维数组赋给一指针,应该这样赋值:

int a[3][4];

int (*p)[4];//该语句是定义一个数组指针,指向含有4个元素的一维数组。

p=a;       //将该二维数组的首地址赋给p,也就是a[0]或&a[0][0];

p++;       //该语句执行过后,也就是p=p+1;p跨过行a[0][]指向了a[1][];

所以数组指针也称指向一维数组的指针,亦称行指针。

#include <stdio.h>

int main(int argc, const char * argv[]) {

int arr[4][3]={12,45,62,21,54,32,85,2,6,48,57,98};

//假设我要定义一个指向数组arr的一个行指针

//a=&a[0]=&a[0][0]=a[0]

//二维数组指针可以替代数组名去使用

int (*p)[3]=arr;//所以这句话就是定义指向二维数组arr的指针变量p

for (int i =0; i<4; i++) {

for (int j=0; j<3; j++) {

//*(*(p+i)+j)就是获取二维数组的每个元素

printf(“%dt”,*(*(p+i)+j));

}

}

return 0;

}

 

10-指针数组和二维数组指针的区别

应该注意指针数组和二维数组指针变量的区别。这两者都可以用来表示二维数组,但是其表示方法和意义是不同的。

二维数组指针变量是单个的变量,其一般形式中”(*指针变量)”两遍的括号不可少。而指针数组类型表示的是多个指针(一组有序的数组)在一般形式中”*指针数组名”两边不能有括号。例如:

int(*p)[3];

表示一个指向二维数组的指针变量。该二维数组的列数是3或者分解为一维数组的长度为3。

int *p[3];

表示是一个指针数组,有三个下标量p[0],p[1],p[2]均为指针变量。

 

16-字符串指针介绍及使用

  1. 字符串指针

C语言中,可以用两种方法访问一个字符串

  1. 字符数组

char string[]=”I love China!”;

printf(“%s”,string);

说明:和前面介绍的数组属性一样,string是数组名,它代表字符数组的首地址。

C语言基础学习笔记16

  1. 字符串指针指向字符串

char *变量名=”字符串内容”;//”字符串内容”是常量

字符串指针变量的定义说明与指向字符变量的指针变量说明是相同的。只能按对指针变量的赋值来区别。对指向字符变量的指针变量应赋予该字符变量的地址。

如:char c;*p=&c;

表示p是一个指向字符变量c的指针变量。

而:char *s=”C Language”;

则表示s是一个指向字符串的指针变量。把字符串的首地址赋予s。

定义的同时进行初始化:

char *ps=”C Language”;

等效于:

char *ps;

ps=”C Language”;

注意:

  1. 使用字符数组来保存的字符串是保存栈里的,保存栈里面东西是可写的,所以我们可以改变里面的字符当,把一个字符串常量赋值一个字符数组的时候,那么它会把字符串常量中的没有字符都放到字符数组里面。
  2. 使用字符指针来保存字符串,它保存的是字符串常量地址,常量区是只读的,所以我们不可以修改字符串中的字符

#include <stdio.h>

#include <string.h>

int main(int argc, const char * argv[]) {

//str只保存字符串的首地址

char *str=”I Love You !”;

//指针变量都占用8个字节

printf(“sizeof(str) = %ldn”,sizeof(str));

//用string库函数strlen才能正确计算长度

printf(“str len = %ldn”,strlen(str));

printf(“%sn”,str);

char ch[]=”abc”;//字符串数组是存在栈区的,所以可读可写

ch[2]=’Z’;

printf(“%sn”,ch);

//但是

//*(str+2)=’X’;//这样写是错误的,因为字符串指针是存在常量区的不可以更改

//在常量区保存的数据都是只读的

printf(“%cn”,*(str+2));//L

return 0;

}

打印结果:

sizeof(str) = 8

str len = 12

I Love You !

abZ

L

  1. 字符串指针使用注意

    1.  可以查看字符串的每一个字符

C语言基础学习笔记16

    1. 不可以修改字符串内容

C语言基础学习笔记16

    1. 妙用字符串指针

将指针变量指向一个格式字符串,用在printf函数中,用于输出二维数组的各种表示的值。但在printf语句中用指针表示PF代替了格式串。这也是程序中常用的方法。

C语言基础学习笔记16

    1. 不能够直接接收键盘输入

C语言基础学习笔记16

C语言基础学习笔记16

C语言基础学习笔记16

#include <stdio.h>

#include <stdlib.h>

int main(int argc, const char * argv[]) {

//str2没有赋值,是野指针

char *str2=NULL;

//要使用函数malloc();必须先导入头文件#include <stdlib.h>_

//这句话的作用是先申请了100个字节的内存给str2,那么str2的首地址就指向了这100内存的首地址

str2=malloc(100);

scanf(“%s”,str2);

printf(“%sn”,str2);

//或者用这种方法

char ch3[100];

char *str3=ch3;

scanf(“%s”,str3);

printf(“%sn”,str3);

return 0;

}

 

17-二维字符数组

二维字符串数组

例如:

char st[3][6]={“china”,”japan”,”korea”};

或者:

char st[][6]={“china”,”japan”,”korea”};

/*可以缺行下标,但不能缺列下标*/

#include <stdio.h>

int main(int argc, const char * argv[]) {

//第一种初始化赋值方法

char str[3][3]={{‘a’,’b’},{‘1′,’2’},{‘s’,’s’}};

for (int i=0; i<3; i++) {

printf(“%sn”,str[i]);

}

//第二种初始化赋值方法

char str2 [3][5]={“abc”,”123″,”kkkk”};

for (int i=0; i<3; i++) {

printf(“%sn”,str2[i]);

}

return 0;

}

 

18-char型指针数组和字符数组的区别

  1. char类型的指针数组

定义了一个指针数组name,并对name作了初始化赋值。其每个元素都指向一个字符串。

char *name[]={

“Monday”,

“Tuesday”,

“Wednesday”,

“Thursday”,

“Friday”

};

  1. 字符串指针变量与字符数组的区别

用字符数组和字符指针变量都可实现字符串的存储和运算。但是两者是有区别的。在使用时应注意一下几个问题:

  1. 字符串指针变量本身是一个变量,用于存放字符串的首地址。而字符串本身是存放在以该首地址为首的一块连续的内存空间中并以’’作为串的结束。字符数组是由于若干个数组元素组成的,它可以用来存放整个字符串。
  2. 对字符串指针方式

char *ps=”C Language”;

可以写为:

char *ps;//ps是一个指针变量,指向可以改变

ps=”C Language”;

而数组方式:

static char st[]={“C Language”};

不能写为:

char st[20];//因为st是一个常量,不能被赋值

st=”Hello”;

而只能对字符数组的各个元素逐个赋值

当一个指针变量在未取得确定地址前使用是危险的,容易引起错误。但是对指针变量直接赋值是可以的。因为C系统对指针变量赋值时要给以确定的地址。

因此,//ps可以重新指向

char *ps=”C Language”;

或者

char *ps;

ps=”C Language”;

 

19-应用:字符串排序

C语言基础学习笔记16

思路:

  1. 排序的规则,按照首字母的ascii码值排序
  2. 借助字符串的比较函数strcmp(str,str2)
  3. 怎么排序?(选择,冒泡)

#include <stdio.h>

#include <string.h>

void sortMaoPaoPX(char *name[]){

int len =6;

for (int i=0; i<len-1; i++) {

for (int j=0; j<len-1-i; j++) {

if (strcmp(name[j],name[j+1])>0) {

char *temp;

temp=name[j];

name[j]=name[j+1];

name[j+1]=temp;

}

}

}

}

void sortXuanZePX(char *str[]){

for (int i=0; i<5; i++) {

for (int j=i; j<5; j++) {

if (strcmp(str[i],str[j])>0) {

char *temp=str[i];

str[i]=str[j];

str[j]=temp;

}

}

}

 

}

 

int main(int argc, const char * argv[]) {

char *str[]={

“CHINA”,

“AUSTRALIA”,

“AMERICA”,

“CANADA”,

“ENGLAND”

};

char *name[]={

“Japan”,

“Corea”,

“Greece”,

“India”,

“Haiti”,

“Benin”

};

printf(“—–冒泡排序法—–n”);

sortMaoPaoPX(name);

for (int i=0; i<6; i++) {

printf(“%sn”,name[i]);

}

printf(“—–选择排序法—–n”);

sortXuanZePX(str);

for (int i=0; i<5; i++) {

printf(“%sn”,str[i]);

}
return 0;

}


本博客内容既有转载自网络的内容,也有本作者原创内容,仅供学习与交流之用
如有侵权或者错误之处,请及时在下方留言!
喜欢 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址