C语言-----指针的一些思考

目录

前言

一、指针是什么?

二、一些题目所带来的思考

1.指针常量与常量指针

2.关于“++”的指针问题

3.定义函数(有关指针) 

4.定义数组指针与函数指针

5.指针与数组 

6.指针赋值 

7.指针取出某个值 

8.二级指针 

9.指针-----输出 

总结




前言

指针是一个比较困难的部分(对我来说),但经过一段时间的学习有了一些思考,希望和大家多多交流


提示:以下是本篇文章正文内容,下面案例可供参考


一、指针是什么?

指针也就是内存地址,指针变量是用来存放内存地址的变量,在同一CPU构架下,不同类型的指针变量所占用的存储单元长度是相同的,而存放数据的变量因数据的类型不同,所占用的存储空间长度也不同。有了指针以后,不仅可以对数据本身,也可以对存储数据的变量地址进行操作。 

指针描述了数据在内存中的位置,标示了一个占据存储空间的实体,在这一段空间起始位置的相对距离值。在 C/C++语言中,指针一般被认为是指针变量,指针变量的内容存储的是其指向的对象的首地址,指向的对象可以是变量(指针变量也是变量),数组,函数等占据存储空间的实体。


二、一些题目所带来的思考


1.指针常量与常量指针

char *const name =new char[5];

A.name[3[='q';

B.name="line";

C.name=new char[5];

D.name=new char('q');

解:本题为指针常量而非常量指针;

常量指针声明: int const *p;const int *p;

将一个常量的地址赋给指针,不允许通过指针来修改内存数据

指针常量声明:int *const p=&a;

指针常量是指针所指向的位置不能改变,即指针本身就是一个常量。

记住!!!

指针和const 谁在前先读谁;

*象征地址,const象征着内容;

谁在前不允许谁改变。 

2.关于“++”的指针问题

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

第一步使b指向a[0], 第二步对a[0]加2, 此时a[0]为3,第三步指针向右移动两位指向a[2]赋予其值2,第四步指针b向右移动1位使其指向a[1];输出结果为2,4

设 int x[]={1,2,3,4,5,6};*p=x;则值为3的表达式为
A.p+=2,*p=x;
B.p+=2,*p++;
C.p+=3,*p;
D.p+=2,++*p;

 答案 :B

*p=x;//p指针指向数组的首地址,p+=2则指针指向数组的第三个元素,而*++p是前置++,p先自增,再解引用,就指向第四个元素

3.定义函数(有关指针) 

函数声明int *swap()的含义为()
A.一个返回整型值的函数swap();
B.一个返回指向整型值指针的函数swap();
C.一个指向函数swap()的指针,函数返回一个整型值;
D.以上说法均错误;

答案:B

一个返回指向整型值指针的函数

int *b();

一个指向函数的指针,函数返回一个整型值

int (*b)(); 

4.定义数组指针与函数指针

定义一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数,并返回一个整型数
A. int *a[10];
B. int (*a)[10];
C. int (*a)(int);
D. int (*a[10])(int);

答案:D

这样的表达式可以遵循如下公式:从左到右,由近及远,括号优先;

例如对A选项:从右向左  先看到[10] 表明这是个数组 ,再看到*,说明其中的数组元素为指针

B选项 括号优先,说明a为指针数组,存放10个int型

C选项 函数指针,指向有一个参数并且返回类型均为int型函数

再看 D选项(*a[10])右边是(int);说明所存的指针是指向有一个int形参的函数指针数组

再看到左边的int;说明其所指向函数的返回值为int型

已知:int a,&ra=a;关于ra的描述中正确的是:

A. ra是int型变量a的地址值;

B. a是int型变量ra的地址值

C. ra是int型变量a的引用;

D.  ra是int型变量a的指针;

 &放在=后面表示取地址,放在前面表示引用。

5.指针与数组 

设有下列程序段:char s[]="china";char *p=s,p与s可以随意替换使用。
答案:false

 数组指针更像是指针的一个真子集,主要用于数组,范围更窄。而指针是可以用于数组乃至更远的地方,同时由于数组指针针对的数组,所以一些方面有特权。比如:sizeof(数组指针)与sizeof(指针),前者为数组长度*指针的范围(以字节为单位),而指针就只是指针范围

6.指针赋值 

已有定义int k=2;int *ptr1,*ptr2;且ptr1和ptr2均指向变量k。下列不正确的赋值语句是()
A. k=*ptr1+*ptr2;
B. ptr2=k;
C. ptr1=ptr2;
D. k=*ptr1*(*ptr2);

若想要赋值则等号左右两边应当为相同的类型但选项B,左侧为指针变量,右侧为常数k显然不对,应当&k的地址 

7.指针取出某个值 

使指针变量p指向元素x[5]的语句为()
double x[10], *p;
int i=5;
A. p= &x[i];
B. p= x;
C. p= x[i];
D. p= &(x+i);

答案:A

 x[i]:为一个值,取地址输入到p;  D中x为指向第一个的数组名,加5后变成指向x[5],然后如果再&(取地址)则重发,出现问题

若有以下定义和语句,则对s数组元素的正确引用形式是()
int s[4][5],(*ps)[5];
ps = s;
A. ps+1;
B. *(ps+3);
C. ps[0][2];
D. *(ps+1)+3;

 答案:C

ps是指向二维数组s的指针(等于二重指针)一次*()解开一次,A为ps+1指向二维数组第二行首地址的指针B.为s数组第四行的首地址;C为第二行第四列元素的地址。

若有语句:int s[3][3],(*p)[3];p=s;则对s数组元素的引用形式正确的是:
A. p+1;
B. *(p+1);
C. p[1][2];
D. *(p+1)+2;

答案:C

int(*p)[3]表示数组指针,指向的元素长度为3的数组。

p+1移动12个字节(3个int型,这里可以理解为二维指针,对 p解一次引用(实际上指的是数组名),需要解两次引用才能指向数组的元素

8.二级指针 

 int main()
{
	 char*** p;
     static char* s[] = { "black","white","pink","violet" };
     char** ptr[] = { s + 3,s + 2,s + 1,s };
     p = ptr;
     ++p;
     printf("%s", **p + 1);
     return 0;
}输出结果为: ink

**p指向pink,***p指向'p', 

题目中**p指向pink,+1指向'i',故输出ink

9.指针-----输出 

 int main()
{
	 char* str[3] = { "stra","strb","strc" };
	 char* p = str[0];
	 int i = 0;
	 while (i < 3)
	 {
		 printf("%s", p++);
		 i++;
	 }
	 return 0;
}
输出结果为:stra tra ra

1.p为char*类型,每次++,后移一位

2.char *str[0]相当于char*p="stra",p先指向s,p++后指向t

3.printf输出遇到空格停止

 int main()
{
	 int a[5] = { 1,2,3,4,5 };
	 int* ptr = (int*)(&a + 1);
	 printf("%d,%d", *(a + 1), *(ptr - 1));
	 return 0;
}输出结果为:2,5

 &a+1,其中+1所偏移为a的整个数组大小,即5个int型

a+1,所偏移的为a中一个元素的大小,即1个int型

ptr-1,ptr原址数组第一位,+5后指向第六位,此时由于强制类型转换,-1偏移的大小为1个int型

 int main()
{
	 int x[5] = { 2,4,6,8,10 }, * p;
	 int(*pp)[5];
	 p = x;
	 pp = &x;
	 printf("%d\n", *(p++));
	 printf("%d\n", *pp);
}输出结果:2和随机值

 p为指针数组,p指向数组的第一位x[0],在第一个printf中,因为后置++,先输出p后再自加1;

对于第二个printf,先定义数组指针(本身是指针,存储整个数组的地址,整个数组的地址表示为(&数组名)->(&x[0]))

ps:数组名(x):单独使用表示的数组首元素的地址

&数组名(&x)表示的是整个数组的首地址。

x与&x 其值相同但意义不同。

‘=’左右两侧的类型一致左边为整个数组指针,右边的数据类型是整个数组的地址

但是解引用就会得到一个随机值,因为pp存放的是整个数组,用printf无法全部打印,故输出随机值

 int main()
{
	 char* a = "Trend";
	 char** b = &a;
	 *b = "commercial";
	 char* c = ++a;
	 a = "talents.";
	 printf("%c/n", *++c);
	 return 0;
}
输出结果:m

 一开始a指向"Trend",b指向指针a,后面commercial的内容通过二维指针b赋给a,改变了a的内容,a指向commercial,指针c指向commercial的第二个字符'o';随后a指向“talent”,但c不发生改变,继续向后平移,c指向‘m’,输出结果。

 int main()
{
	 char* s = "abcde";
	 s += 2;
	 printf("%d", s);
	 return 0;
}
输出了‘c’的地址

 指针s本来指向的数组的第一个元素'a';后来向左移2位指向‘c’,格式化输出s就是字符‘c’的地址



总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值