c语言_day5

目录

指针和数组

指针和一维数组

练习:

二维数组

数组指针

指针数组

应用场景:

1)存放普通变量的地址

2)存放二维数组的每一行第一个元素的地址(列地址)

3)存放字符串


指针和数组

直接访问:通过数组名访问

间接访问:通过指针访问

指针和一维数组

int a[5]={5,6,4,2,8};
int *p=a;

直接访问:

取地址

元素

取元素

a

&a[0]

5

a[0]

*a

a+1

&a[1]

6

a[1]

*(a+1)

a+2

&a[2]

4

a[2]

*(a+2)

a+3

&a[3]

2

a[3]

*(a+3)

a+4

&a[4]

8

a[4]

*(a+4)

间接访问:

取地址

元素

取元素

&p[0]

p

5

*p

p[0]

&p[1]

p+1

6

*(p+1)

p[1]

&p[2]

p+2

4

*(p+2)

p[2]

&p[3]

p+3

2

*(p+3)

p[3]

&p[4]

p+4

8

*(p+4)

p[4]

a和p本质不一样:a是地址常量,p是变量;a不能执行++操作,p可以

访问数组元素a[i]的值:

   直接访问:a[i]      *(a+1)

   间接访问:p[i] *(p+1)

访问数组元素a[i]的地址:

   直接访问:&a[i]    a+i

   间接访问:&p[i]    p+i

运算方法:

     1)++和*都是单目运算符,优先级相同

     2)单目运算符从右向左运算

(*p)++:首先取出指针 p 指向的内存地址处的值,然后对取出的值进行自增值加1,将自增后的值存回原来的内存地址

*p++:单目运算符先算p++,由于++在后,取p指向的内存地址处的值;后对地址进行++

++*p:先取指针p的值,再对值自增

++(*p):同上

*++p: p自加,取自加后的值

*(++p): 同上

*(p++):先算p++,由于++在后,取p指向的内存地址处的值;后对地址进行++

练习:

1.

2.

3.

补充:

char *p="hello";

        // p在栈区开辟4字节空间存放字符串常量"hello"的首地址

        // hello存放在常量区

char buf[33]="hello";

        // buf:在栈区开辟32字节空间,存放"hello"字符串

二维数组

如:

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

a:数组名,表示第一行的首地址

a+1:第二行首地址

a是行地址,怎么用a表示列?

行地址和列地址级别不一样,一行可以有多列,所以行地址大于列地址,,,,所以要降级

在a前边加*,表示把行地址降级为列地址

*a:第一行第一列的地址 a[0]

*a+1:第一行第二列

*(a+1):第二行第一列

*(a+1)+1:第二行第二列

地址

元素

a[0]

*a

a

1

a[0][0]

**a

*a[0]

a[0]+1

*a+1

2

a[0][1]

*(*a+1)

*(a[0]+1)

a[0]+2

*a+2

3

a[0][2]

*(*a+2)

*(a[0]+2)

a[1]

*(a+1)

a+1

4

a[1][0]

**(a+1)

*a[1]

a[1]+1

*(a+1)+1

5

a[1][1]

*(*(a+1)+1)

*(a[1]+1)

a[1]+2

*(a+1)+2

6

a[1][2]

*(*(a+1)+2)

*(a[1]+2)

访问a[i][j]的地址:

*(a+i)+j &a[i][j] a[i]+j

访问a[i][j]的值:

a[i][j] *(*(a+i)+j) *(a[i]+j)

练习:

数组指针

美丽的人

本质是指针,指向数组   行指针

格式:存储类型 数据类型      (*指针变量名)[列数]

int a[2][3]={2,3,4,5,6};
    int (*p)[3]=a;
    printf("%p %p\n",a,a+1);
    printf("%p %p\n",p,p+1);

地址

p[0]

*p

a

p

1

**p

*p[0]

p[0]+1

*p+1

2

*(*p+1)

*(p[0]+1)

p[0]+2

*p+2

3

*(*p+2)

*(p[0]+2)

p[1]

*(p+1)

a+1

p+1

4

**(p+1)

**p[1]

p[1]+1

*(p+1)+1

5

*(*(p+1)+1)

*(p[1]+1)

p[1]+2

*(p+1)+2

6

*(*(p+1)+2)

*(p[1]+2)

大小:

sizeof(p)==4

注意:指针大小是一定的,不因指向的内容而改变,只跟操作系统有关;就Linux而言,32位为4字节,64位为8字节。

指针数组

本质是数组,里边存放指针

格式:

存储类型 数据类型 *数组名[元素个数]

int  *arr[2];

应用场景:

1)存放普通变量的地址

int a=10,b=20,c=30;
int *p[3]={&a,&b,&c};
访问数组元素:数组名[下标];指针数组存放的内容是地址
p[0]------->&a
p[1]------->&b
p[2]------->&c
printf("%p %p\n",p[1],&b);

访问b的地址:(数组的第二个元素)
	p[1]
	*(p+1):p是数组首地址,p+1访问数组第二个元素的地址,*(p+1)取内容

访问b的值:
	*p[1]
	*(*(p+1))

2)存放二维数组的每一行第一个元素的地址(列地址)

int a[2][3]={1,2,3,4,5,6};
int *p[2]={a[0],a[1]};
访问a[1][2]的地址:(数组第二行第三列)
	p[1]+2:p[1]先取数组第二个元素(a[1]第二行第一列的地址),p[1]+2向后移动2个数据单位
	*(p+1)+2:p数组首地址,p+1取指针数组第二个元素的地址,*(p+1)取指针数组第二个元素(a[1]),*(p+1)+2

访问a[1][2]的值:
	*(p[1]+2)
	*(*(p+1)+2)

3)存放字符串

char  *p[3]={"hello","world","hqyj"};
打印"world"字符串:
	printf("%s\n",p[1]);
	printf("%s\n",*(p+1));
打印'd'这个字符:
	*(p[1]+4):p[1]获取指针数组第二个元素的值("world"的首地址),向后移动4个数据单位
	*(*(p+1)+4):p数组首地址,p+1取指针数组第二个元素的地址,*(p+1)取指针数组第二个元素(a[1])("world"的首地址),向后移动4个数据单位,取内容

4)main函数命令行参数

int main(int argc, char const *argv[])
argc:表示argv里存放的数据的个数,也就是命令行存放的字符串
argv:是指针数组,里边存放命令行传递的字符串  ./a.out
printf("%s %d\n",argv[1],argc);

./a.out  hello  world

练习:

已有定义int k=2;int *ptr1,*ptr2;且ptr1和ptr2均已指向变量k,下面不能正确执行的赋值语句是    。
A)k=*ptr1+*ptr2     B)ptr2=k         C)ptr1=ptr2       D)k=*ptr1*(*ptr2)
若有语句:int *p,a=4;和p=&a;下面均代表地址的一组选项是              。
A)a,p,*&a           B)&*a,&a,*p        C)*&p,*p,&a        D)&a,&*p,p
下面判断正确的是              。
A)char *a=”china”; 等价于 char *a; *a=”china” ;
B)char str[10]={“china”}; 等价于 char str[10]; str[ ]={“china”} ;
C)char *s=”china”; 等价于 char *s; s=”china” ;
定义一个指针,指针存放地址   "china"存放在字符串常量区,常量区首地址赋值给指针
D)char c[4]=”abc”,d[4]=”abc”; 等价于 char c[4]=d[4]=”abc” ;
下面程序段中,for循环的执行次数是              。
char *s=”\t a \014 b c” ;
for (  ; *s!=’\0’ ; s++)  printf(“*”) ;
A)2                B)7                C)6                D)5
设有程序段:char s[10]=”china”; char *p ; p=s ;则下面叙述正确的是             。
A)s和p完全相同
B)数组s中的内容和指针变量p中的内容相等
C)s数组长度和p所指向的字符串长度相等
D)*p与s[0]相等
下面程序段的运行结果是             。
   char a[ ]=”language” , *p ;
   p=a ; 
   while (*p!=’u’) { printf(“%c”,*p-32); p++ ; }
A)LANGUAGE       B)language            C)LANG       D)langUAGE
设有说明语句:char a[]=”It is mine”;char *p=”It is mine”;则以下不正确的叙述是              
A)a+1表示的是字符t的地址                   
B)p指向另外的字符串时,字符串的长度不受限制
C)p变量中存放的地址值可以改变
D)a中只能存放10个字符 
若有程序段:int a[2][3],(*p)[3]; p=a;则对a数组元素的正确引用是            。
A)(p+1)[0]           B)*(*(p+2)+1)        C)*(p[1]+1)          D)p[1]+2
下面程序的运行结果是              。
main ( )
{  int x[5]={2,4,6,8,10}, *p, **pp ;
   p=x , pp = &p ;
   printf(“%d”,*(p++));
   printf(“%3d”,**pp);
}
A)4  4            B)2  4              C)2  2                D)4  6
若有说明:char *language[]={“FORTRAN”,”BASIC”,”PASCAL”,”JAVA”,”C”};则language[2]的值是             。
A)一个字符        B)一个地址          C)一个字符串          D)一个不定值
有以下程序段 
#include <stdio.h>
int main()
{   int x[] = {10, 20, 30};  
    int *px = x;
printf("%d,", ++*px);   printf("%d,", *px);//11  11   {11,20,30}
px = x;
printf("%d,", (*px)++);  printf("%d,", *px); //11  12  {12,20,30}
 px = x;
 printf("%d,", *px++);   printf("%d,", *px); //12   20  {12,20,30}
 px = x;
printf("%d,", *++px);    printf("%d\n", *px); //20  20
return 0;
}
程序运行后的输出结果是(   ) 
A)11,11,11,12,12,20,20,20		 B)20,10,11,10,11,10,11,10
C)11,11,11,12,12,13,20,20        D)20,10,11,20,11,12,20,20
const char *p、char const *p、char *const p 有什么区别?(北京信果科技)
请写出输出结果 (晟安信息)
int main()
{
    int a[10] = {0};
    int *p = a;
    int *q = &a[6];
    printf("%d\n", q-p);	//6
    printf("%d\n", (int)q - (int)p);//4*6=24
}
以下为linux下的32位C程序  (飞音时代)
char str[] = "Hello"; char *p = str; int n = 10;
请计算:
(1) sizeof(str) = ___6_____		(2) sizeof(p) = ___4_____
(3)sizeof(n) = ___4____		
下列程序输出结果是?  
#include <stdio.h>
int a[] = {0, 2, 4, 6, 8};
main()
{
    int i;
    int *p = a;
    for(i = 0; i < 4; i++) a[i] = *p++;
    printf("%d\n", a[2]);     
}


写出下面的声明:
(1) 指向常整形数的指针(整形数是不可修改的,但指针可以)
______________________________________________________________
(2) 指向整型数的常指针(指针指向的整型数是可以修改的,但指针是不可修改的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值