C语言里面的指针问题
来源:互联网 发布:文华财经mac版 编辑:程序博客网 时间:2024/05/17 16:13
一、变量与指针
1.变量
C语言中每次声明一个变量,则内存在会申请一个该变量类型应该占据的空间.
假设int类型占四个字节(不同系统的字节数不同),那么语句
int a;
a=10;
即在内存中申请了四个字节的空间,并将其命名为a,其值为10.
2.变量地址
int型变量a在内存有一个具体的地址编号,用 &a 可以读取到,如print(“%d”,&a);即可打印出变量a的内存地址编号。
3.指针变量
指针其实也是一种变量,语句 int* pointer;即在内存中申请了int类型变量的空间,将其取名为pointer.
它和之前的a其实没有本质不同。区别在于,pointer的内容是某个int变量的地址。
如 pointer = &a即把变量a的地址赋给pointer。
那么通过语句printf(“%d”,*pointer)即可打印出a,这里*pointer即为按照pointer的内容寻址,得到的具体变量内容。
这里pointer里面存的是a的地址,那么按照该地址寻找就得到变量a了,*pointer就显示出a的内容,即为10;
4.思考
假设给出这样一段代码:
int a, *pi;
a = 10;
pi = &a;
*pi = 20;
printf("%d", a)
那么打印出的a值是多少?(20)
二、数组与指针
1.C语言中定义一个数组,那么数组名实质上是个指针"常量",比如
int a[]={1,2,3,4};
printf("%d",a); //得到的是内存位置
printf("%d",*a); //得到第一个元素
printf("%d",*(a+1)); //得到第二个元素
那么打印a得到的就是数组第一个元素所在的内存编号位置,打印 *a 得到的就是1。
需要注意的是打印*(a+1)得到恰好是第二个元素,因为a是指针变量,加1其实是加一个int类型的宽度
所以 a+1得到的是后一个元素的位置,从而 *(a+1)即可得到第二个元素。
再者,a是一个常量,若使用 a++ 这样的赋值语句会出现编译报错。
不过可以将a的值赋给一个指针变量pi,从而就可以使用 pi++ 这样的语句进行遍历:
int i, *pi, a[]={1,2,3,4}
pi = a //将a的值赋给pi,pi就记录了数组的起始位置
for(i=0;i<4;i++)
{
printf("%d\n", *pi);
pi++; //这两句语句也可以用printf("%d", pi[i])代替,其中pi[i]与a[i], *(pi+i), *(a+i)等价
}
以上代码就依次打印出了数组a的元素,循环里的pi不能用a代替。
2.指针常量
除了指针变量,我们也可以声明一个指针常量,如下:
int i, a[]={1,2,3,4}
int * const pi = a //注意const的位置
此时pi就无法进行1中的遍历,因为此时pi已经是个常量了。
需要注意的是一般定义数组时:
int * const a ={1,2,3,4} //这样不行
int a[] = {1,2,3,4} //可以,一般定义数组的方式
3.const关键字与指针
用const修饰过的变量不能进行重新赋值,如:
const int ic=20; //这句等价于int const ic = 20,int和const哪个放前面都可以
ic = 40 //这句编译会出错
那么const修饰指针变量时,会出现 const int * a, int const * a, int * const a 这三种情况,其实前两种等价;
首先看 const int * pi,这里const修饰的是*pi,所以不能对*pi直接重新赋值,但是pi所指向的那个变量可以重赋值
int a = 10;
int b = 20;
const int *pi = &a
pi = &b //pi是可以重赋值的,const修饰的是整个 *pi
b = 40; //这里可以用 *pi=40 来更新值吗?不行,const修饰了*pi
printf("%d",*pi); //得到的是40
这里 pi还是可变的,只是不能直接对 *pi进行修改,那么如果想让 pi无法更改怎么办呢?这对应第三种情况。
对于 int * const pi,这里 pi 是个常量了,不能重新赋给它另外一个地址值,但是此时可以对 *pi重赋值
int a = 10;
int b = 20;
int * const pi = &a;
//pi = &b是错的,pi无法再指向另外一个地址
a = 80; //这里可以用*pi = 80来代替
printf("%d",*pi);
所以总结如下:
当const修饰在 pi 前,那么pi是个不可更改的值,永远指向一个地址,但可以通过*pi=xx来更改所指的变量的值。
当const修饰在*pi前,那么不能出现*pi=xx这样的语句,pi可更改,pi所指向的变量也可以更改。
4.const类型指针与const类型变量
有三种情况。
情况一:int *pi指针指向const int i常量
const int a = 10;
int *pi;
pi = &a; //此种情况下据说VC会报错,因为pi指向a,那么就可以通过pi更改a的值,违背了代码初衷
pi = (int*) &a //强制转换,VC编译通过,但是仍不能*pi=xx来修改a的值
但是上面的代码在CodeBlocks下面可编译通过,也能修改a的值,不过一般最好不要这么写
情况二: const int *pi指针指向const int i1
const int a = 10;
const int *pi;
pi = &a; //编译通过,不过此时无法通过*pi或者a来更新变量的值,但pi可以重赋值为另一个变量地址
情况三:用const int * const pi声明的指针
int i;
const int * const pi = &i; //此时pi不能更改,*pi亦不能更改
- C语言里面的指针问题
- C语言指针问题
- c语言指针问题
- C语言指针问题
- c语言指针问题
- c语言指针问题
- c语言指针问题
- C语言-指针问题
- c语言指针使用的注意问题
- C语言指针的一些问题
- 一个简单的 C 语言指针问题
- [C语言]关于运用指针的问题。
- c语言数组指针的问题
- 还是C语言的指针问题。。
- C语言指针的赋值问题
- C语言数组与指针的问题
- C语言的指针大小问题
- c语言的数组与指针问题
- Linux编程学习之进程间通信篇-无名管道
- 批处理脚本bat设置IP地址
- 学习曲线
- Centos7下安装MySQL-5.7.15
- CSS基础(二) 个人笔记
- C语言里面的指针问题
- 还原:因为数据库正在使用,所以无法获得对数据库的独占访问权
- LeetCode 650 2 Keys Keyboard
- Elasticsearch Network Settings
- 第一篇博客
- jQuery实现菜单的隐藏和显示
- Uva 10474(lower_bound()的使用) 大理石在哪
- 【剑指Offer】面试题65:滑动窗口的最大值
- 按钮被点击后屏蔽点击且倒计时60S能再次被点击和JS实现和JQuery实现