c语言笔记(9.1.1取地址~9.1.2指针~9.2.1)

本文详细讲解了C/C++中的取地址运算符sizeof和指针概念,包括指针变量的定义、取址运算、指针运算(如加减和比较)、指针与数组的关系,以及常见的指针使用误区和指针运算技巧。涵盖了交换变量值、函数返回值、数组参数传递等实用场景,并探讨了const指针及其限制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

9.1.1取地址运算

sizeof

是一个运算符,给出某个类型或变量在内存中所占据的节字数  sizeof(int)  sizeof(i)

运算符&

scanf("%d",&i);里的&

获得变量的地址,它的操作数必须是变量

int i;printf("%x",&i);

地址大小是否与int相同取决于编译器

int i;printf("%d",&i);

&不能对没有地址的东西取地址

&(a+b)?   &(a++)?    &(++a)?取地址符的右边必须有一个明确的变量,才可以取

相邻的位置数组之间的差距是4!(&a==a==a[0])

9.1.2指针:指针变量就是记录地址的变量

scanf

如果能够取得的变量的地址给一个函数,能否通过这个地址在那个函数内访问这个变量?

scanf("%d",&i);

scanf()的原型应该是什么样子?我们需要一个参数能保存别的变量地址,如何表达能够保存地址的变量?

指针

就是保存地址的变量

int i;

int* p=&i;*表示p是指针  指向int  将i的地址交给p(p里面的值就是i里面的地址,就叫做p指向i)

int * p,q;*靠近谁都表示p是指针 q是普通的int类型变量(*加给了p使得p成了指针)

int  *p,q;

指针变量

变量的值是内存的地址

普通变量的值是实际的值

指针变量的值是具有实际值的变量地址

作为参数的指针

void f(int *p)

在被调用的时候得到某个变量的地址:

int i=0;f(&i);

在函数里面可以通过这个指针访问外面的这个i

访问那个地址上的变量*

*是一个单目运算符,用来访问指针的值所表示的地址上的变量

可以做右值也可以做左值

int k=*p;

*p=k+1;

传入地址

为什么

int i;scanf(“%d”,i);

编译没有报错?

9.1.3指针的使用

指针使用场景1:交换两个变量的值(swap函数)

void swap(int *pa,int *pb)
{
     int t=*pa;
     *pa=*pb;
     *pb=t;
}

指针使用场景2a

函数返回多个值,某些值就只能通过指针返回

传入的参数实际上是需要保存带回的结果的变量

指针使用场景2b

函数返回运算的状态,结果通过指针返回

常用的套路是让函数返回特殊的不属于有效范围内的值来表述出错

-1或0(在文件操作会看到大量的例子)

但是当任何数值都是有效的可能结果时,就得分开返回了

指针最常见的错误

定义了指针变量,还没有指向任何变量,就开始使用指针

9.1.4指针与数组

传入的函数的数组成了什么?

函数参数表中的数组实际上是指针

sizeof(a)==sizeof(int*)

但是可以用数组的运算符[]进行运算

数组参数

以下四种函数原型是等价的:

int sum(int*ar,int n);

int sum (int*,int);

int sum(int ar[ ],int n);

int sum(int [ ],int);

数组变量是特殊的指针

数组变量本身表达地址,所以int a[10];int*p=a;//无需用&取地址

但是数组的单位表达的数量,需要用&取地址

a==&a[0]

[ ]运算符可以对数组做,也可以对指针做:

p[0]<==>a[0]

*运算符可以对指针做,也可以对数组做

数组变量是const的指针 所以不能被赋 值

9.1.5

指针是const

表示一旦到了某个变量的地址,不能再指向其他变量

int *const q=&i://q是const,q指向i的事实不能改变,q不能指向别人不能改变。

*q=26;//OK;

q++;   //ERROR

所指是const

表示不能通过这个指针去修改变量(并不能使得那个变量成为const)

const int*p=&i;

*p=26;//ERRORR!(*p)是const

i=26;//OK

p=&j;//OK

int i;

const int* p1=&i;

int const * p2=&i;

int  *const p3=&i;

判断哪个被const了的标志是const在*的前面(他所指的东西不能被改)还是后面(指针不能被修改)

转换

总是可以把一个非const的值转换成const的

void f(const int* x);
int a =15;
f(&a);//ok
const int b=a;

f(&b);///ok
b=a+1;//Error!

当要传递的参数的类型比地址大的时候,这是常用的手段:既能用比较少的字节传递值给参数,又能避免函数对外面的变量的修改

const数组

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

数组变量已经是const的指针了,这里的const表明数组的每个单元都是const int

所以必须通过初始化进行赋值

保护数组值

int sum(const int a[],int length);

9.2.1指针运算

算术运算这些可以对指针做:

给指针加,减一个整数(+,+=,-,-=)

递增递减(++/——)

两个指针相减

*p++

取出p所指的那个数据来,完事之后顺便把p移到下一个位置去

*的优先级虽然高,但是没有++高

常用于数组类的连续空间操作

在某些CPU上,这可以直接被翻译成一条汇编语言

指针比较

<,<=,==,>,>=,!=都可以对指针做

比较它们在内存中的地址

数组中的单元的地址肯定是线性递增的

0地址

当然你的内存中有0地址,但是0地址通常是个不能随便碰的地址

所以你的指针不应该具有0

因此可以用0地址来表示特殊的事情:

返回的指针是无效的

指针没有被真正初始化(先初始化为0)

NULL是一个预定定义的符号,表示0地址

有的编译器不愿意你用0地址来表示0地址

指针的类型

无论指向什么类型,所有的指针的大小都是一样的,因为都是地址

但是指向不同类型的指针是不能直接相互赋值的

这是为了避免用错指针                 

指针的类型转换

void*表示不知道指向什么东西的指针

计算时与char*相同(但不相通)

指针也可以转换类型

int *p=&i;void*q=(void*)p;

这并没有改变p所指的变量的类型,而是让后人用不同的眼光通过p看他所指的变量

我不在当你是int啦,我认为你是个void!

用指针来做什么

需要传入较大的数据时用作参数

传入数组后对数组做操作

函数返回不止一个结果

需要用函数来修改不止一个变量

动态申请的内涵.......

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值