基础指针学习笔记
这是一个变量 a
1 |
|
a
变量的地址的表达式为 &a
你想要把变量 a 的地址存下来,就用
1 |
|
或者
1 |
|
这两种是一样的,但是推荐第一种因为看着不会乱
想要表示 地址 p
对应的 变量,就用 *p
,在这里 *p
完全相当于 a
这下面两行效果是完全一样的
1 |
|
然后还有,注意这下面两种是不一样的
1 |
|
另外还有一个容易混淆的 引用,相当于给变量 a
起别名 b
:
1 |
|
或者
1 |
|
这两种也是一样的,但是依然推荐第一种因为看着不会乱
基础指针内容到此为止
简单概括指针内容:
已知变量 int a
:
a;
这是变量&a
这是 a 的地址
令 int* p = &a
:
p
相当于&a
*p
相当于a
也就是说
&变量
就相当于变量的地址int* 地址
就是申请了一个地址变量*地址
就相当于该地址对应的变量
另外
int& b = a
相当于给变量a
起别名b
上例题
例 1
输入 \(n\) 个变量,使用指针变量访问输出。
分析:数组的存储对应的地址是连续的,所以可以对地址以此加一来取数组的值。
1 |
|
例 2
编写函数交换变量 a、b 的值。
(错误)
1 |
|
程序之所以错误,是因为在函数的入口处,int x
相当于 int x = a
,y
同理,所以 x
和 y
交换并不会改变 a
、b
的值;
(正确,指针)
1 |
|
程序在函数入口处传进 a、b 的地址,并在函数内对这两个地址对应的变量进行操作,所以正确。
(正确,引用)
1 |
|
程序在函数入口处函,int& x
相当于 int& x = a
,y
同理,所以 x
和 y
相当于 a
和 b
的别名,并且对这两个数的值进行交换。
再谈字符数组与指针
我们读入并且输出字符数组的时候,用法如下: 1
2
3char s[101];
scanf("%s",s);
printf("%s",s);scanf
的 s
并不用且不能写成 &s
,因为我们在例题一中其实就有提过,这里的 s
就相当于 &s[0]
。
读者可能会问,既然我们在 printf() 函数中传入的是 &s[0],printf() 函数怎么判断字符串的长度呢?
其实无论是使用 scanf() 函数读入字符数组,还是初始化字符数组,字符数组最后一位的下一位会有一个 '\0'
表示字符串已结束。
例 3
定义一个函数,使用指针传参来实现两个字符串的拼接,将结果存储在第一个字符串指针指向的内存空间中。要求第一个字符串有足够的空间来存放拼接后的结果。并在主函数中定义两个字符串,调用该函数,并输出拼接后的结果。
这道例题的代码是用网上的代码修改的,其思路和巧妙程度让我叹为观止。理解好这个程序,相信读者能对指针的应用能有更深入的理解。
1 |
|
注意:这里的相当代码只是便于读者理解代码的执行顺序,其作用可能略有差别
这里第四行 while (*p1++);
相当于 while(*(p1++));
,也相当于
1 |
|
而 while(*p1)
作用相当于又相当于 while(*p1 != '\0')
('\0'
的 ASCII 码是 0),即将 p1 的地址移到 '\0'
处停止,然后即使停止了,仍然会执行一次 p1++,所以要在第五行,重新执行一次 p1--,让 p1 的地址保持在 '\0'
处;
然后再下一行相当于 while (*(p1++) = *(p2++) != '\0');
相当于依次执行下列代码 1
2
3
4
5
6
7
8
9*p1=*p2;
while(*p1)
{
p1++;
p2++;
*p1=*p2;
}
p1++; // 注意:尽管当 while 的条件 *p1 已经为 false 了,不再执行 while 循环括号里面的内容了,但是 p1++ 和 p2++ 依然会执行最后一次
p2++;'\0'
结束。
好耶,那么这期博客就到这里结束啦(错乱)
写这个写了三天呢,希望能赶紧回去读书吧!