小学生都看得懂的C语言入门(5): 指针
现在已经学到C语言的后面了, 快学完咯....
(一)取地址运算
先来看一下sizeof 计算所占字节
#include<stdio.h>
int main()
{
int a;
a=;
printf("%d\n",sizeof(int));//
printf("%d\n",sizeof(double)); //
printf("%d\n",sizeof(a));//
return ;
}
之前 ,我们看到scanf("%d", &x); 中& 表示什么意思?
& 是为了获取变量的地址, 它的操作对象必须是变量,
#include<stdio.h> int main()
{
int i=;
printf("%p\n",&i); // 打印地址
return ;
}
得到 000000000062FE4C
#include<stdio.h> int main()
{
int i=;
int j;
printf("%p\n",&j);
printf("%p\n",&i);
return ;
}
得到
000000000062FE48
000000000062FE4C
C与8 在16进制下相差4,(c相当于12); 说明在内存中他们两个是紧挨着放的,
C语言中分配变量是从顶向下的, 先定义的变量i 的地址更高, 后定义的变量j 的地址更低.
#include<stdio.h>
int main()
{
int a[];
printf("%p\n",&a);
printf("%p\n",a);// 直接拿a 作为地址
printf("%p\n",&a[]);
printf("%p\n",&a[]);
return ;
}
得到
000000000062FE20
000000000062FE20
000000000062FE20
000000000062FE24
那么 可见 & a= a, 表示a[0]的地址.
(二)拿什么东东来记录变量的地址??? ----指针
首先介绍下:
#include<stdio.h>
int i;
int *p=&i;// 一般用p表示指针(point), p获得i的地址,p指向i
int *p,q; // p q 都是指针
int* p,q; // 只有p是指针
//指针变量
//指针变量的值是内存的地址,普通变量的值是实际的值,
void f(int *p);// 作为参数的指针
int i=;f(&i);// 进行调用.. 取得地址进行调用
#include<stdio.h>
void f(int *p);
int main()
{
int i=;
printf("&i=%p\n",&i);
f(&i);
return ;
} void f(int *p)
{
printf(" p=%p\n",p);
}
得到
&i=000000000062FE4C
p=000000000062FE4C
对比下
#include<stdio.h>
void f(int *p);
void g(int k);
int main()
{
int i=;
printf("&i=%p\n",&i); // &i=000000000062FE4C
f(&i); // p=000000000062FE4C
g(i);//
return ;
} void f(int *p)
{
printf(" p=%p\n",p);
} void g(int k)
{
printf("i=%d\n",k);
}
// 访问那个地址上的变量 *
// * 是一个单目运算符,用来访问指针的值所表示的地址上的变量.
int k=*p;
*p=k+1;
#include<stdio.h>
void f(int *p);
void g(int k);
int main()
{
int i=;
printf("&i=%p\n",&i); // &i=000000000062FE4C
f(&i); // p=000000000062FE4C
g(i);//26 , 在f中被更改!!
return ;
} void f(int *p)
{
printf(" p=%p\n",p);
printf("*p=%d\n",*p);
// 在f中得到了地址, *p 可以看成是一个 int 得到*p=6;
*p=; // 能够改变i的值?? 可以!!
} void g(int k)
{
printf("i=%d\n",k);
}
&i=000000000062FE4C
p=000000000062FE4C
*p=6
i=26
(三) 数组作为函数参数机理
之前提到过, 数组作为函数参数后, 函数内不能用sizeof 了, 这是为啥??
#include<stdio.h>
void minmax(int a[],int len,int *min,int *max);
int main(void)
{
int a[]={,,,,,,,,};
int min,max;
printf("main 中 sizeof(a)=%lu\n",sizeof(a)); //36
printf("main 中a的地址 a=%p\n",a); // a=000000000062FE20
minmax(a,sizeof(a)/sizeof(a[]),&min,&max);
printf("a[0]=%d\n",a[]);// 100 能够输出100!!
printf("min=%d,max=%d\n",min,max);
return ;
}
void minmax(int a[],int len,int *min,int *max)
{
int i;
printf("minmax中 sizeof(a)=%lu\n",sizeof(a));//8
printf("minmax 中a的地址 a=%p\n",a); // a=000000000062FE20, 与上述一样?
// 这是为什么? 这里的a 就是指针啊!!
a[]=; // 不妨更改a[0]看看能够传递到main中
*min=*max=a[];
for(i=;i<len;i++) {
if(a[i]<*min){
*min=a[i];
}
if(a[i]>*max){
*max=a[i];
}
} }

上述也说明了数组 作为函数的参数实际上就是指针, 这就解释了为什么在 函数参数中, 用int a[] , 方括号中不写数字, 函数中没法用sizeof 得到正确的元素个数了. int a[] 其实就是指针, 虽然看着是数组, 若把它改为指针, 得到
#include<stdio.h>
void minmax(int *a,int len,int *min,int *max);
int main(void)
{
int a[]={,,,,,,,,};
int min,max;
printf("main 中 sizeof(a)=%lu\n",sizeof(a)); //36
printf("main 中a的地址 a=%p\n",a); // a=000000000062FE20
minmax(a,sizeof(a)/sizeof(a[]),&min,&max);
printf("a[0]=%d\n",a[]);//100
printf("min=%d,max=%d\n",min,max);
return ;
}
void minmax(int *a,int len,int *min,int *max)
{
int i;
printf("minmax中 sizeof(a)=%lu\n",sizeof(a));//36
printf("minmax 中a的地址 a=%p\n",a); // a=000000000062FE20, 与上述一样?
// 这是为什么? 这里的a 就是指针啊!!
a[]=; // 不妨更改a[0]看看能够传递到main中
*min=*max=a[];// 指针形式, 下面做改变可以传到main中去
for(i=;i<len;i++) {
if(a[i]<*min){
*min=a[i];
}
if(a[i]>*max){
*max=a[i];
}
} }
上述编译没有问题, 现在*a 是指针, 可是a[0] ,a[i] 都是当做数组在用它,
// 数组与指针存在某种联系!!
以下几种函数原型(之前写函数声明的地方)是等价的:
int sum(int a,int n);
int sum( int* ,int);
int sum( int ar[],int n);
int sum(int[], int);
数组变量是特殊的指针, 之前对数组a取地址可以不加& !!
printf("%p\n",&a);
printf("%p\n",a);// 直接拿a 作为地址
printf("%p\n",&a[0]);
,这三个一样的结果!!
(1) 但是对单个元素需要加&, 例如&a[1];
(2) [ ] 可以对数组做,也可以对指针做, p[0] 等价于 a[0]
(3) * 运算既可以对数组做, 也可以对指针做,
(4) 数组变量是 const 的指针, 不能被赋值
int a[]={,,};
int b[];// int b[]=a;也是错误的!!
b=a;
这样是错误的!!
下面两个是正确的:
int a[]={,,};
int *q =a; //可以
int b[] ; // 相当于 int * const b; 是个常量指针
小学生都看得懂的C语言入门(5): 指针的更多相关文章
- 小学生都看得懂的C语言入门(1): 基础/判别/循环
c基础入门, 小学生也可以都看得懂!!!! 安装一个编译器, 这方面我不太懂, 安装了DEV-C++ ,体积不大,30M左右吧, 感觉挺好用,初学者够了. 介绍下DEV 的快键键: 恢复 Ctrl+ ...
- 小学生都看得懂的C语言入门(6): 字符串
1.字符用 char 表示 #include<stdio.h> int main() { char c; char d; c=; d='; if (c==d){ printf(" ...
- 小学生都看得懂的C语言入门(4): 数组与函数
// 之前判断素数, 只需要到sqrt(x)即可,//更加简单的, 判断能够比已知的小于x的素数整除, 运行更快 #include <stdio.h> // 之前判断素数, 只需要到sqr ...
- 小学生都看得懂的C语言入门(3): 数组与函数
#include <stdio.h> int main() { int x; ; ; scanf("%d",&x){ sum+=x; cnt++; scanf( ...
- 小学生都看得懂的C语言入门(2): 判别 循环的一些应用实例
1.bool 类型 定义bool类型之前需要导入#include <stdbool.h> #include <stdio.h> #include <stdbool.h&g ...
- C语言入门理解指针
本文章为本人原创,适合于刚入坑C语言,对于指针的定义和用法模糊不清的同学,如有不正,请各位指出. 从根本来说,指针变量也是变量,只是int变成了int *,以此类推.只不过指针变量里面放的内容是普通变 ...
- 小学生都能读懂的网络协议之:WebSocket
目录 简介 webSocket vs HTTP HTTP upgrade header websocket的优点 webScoket的应用 websocket的握手流程 WebSocket API 总 ...
- 胖虎都看得懂的CSS入门
CSS入门 CSS是什么 摘自维基百科 层叠样式表(英语:Cascading Style Sheets,简写CSS),又称串样式列表.级联样式表.串接样式表.层叠样式表.階層式樣式表,一种用来为结构化 ...
- 小白都看得懂的Javadoc上手教程
Javadoc是什么 官方回答: Javadoc is a tool for generating API documentation in HTML format from doc comments ...
随机推荐
- 表单相关标签之form标签
表单能够包含 input 元素,比如文本字段.复选框.单选框.提交按钮等等. 表单还可以包含 menus.textarea.fieldset.legend 和 label 元素以及其它块级元素 表单用 ...
- python 中的"*"与"**"
1.Python中 *和**很常见的运算符的用途及其多种使用方式. 本文所述的*和**,指的是*和**前缀运算符,而不是中缀运算符. 所以指的不是乘法和乘幂: 使用*和**将参数传递给函数 使用*和* ...
- renren-security旧版本 分模块 的模块之间关系浅析
Maven结构,一个父模块 六个子模块 七个pom.xml: \git\renren-security\pom.xml <modules> <module>renren-com ...
- Mybatis--课程中循序渐进的体会 《黑马程序员_Springmvc+Mybatis由浅入深全套视频教程video》
mybatis 刚开始是用最原始的方法开发了一个入门程序,(没有dao) 1.将数据源配置在SqlMapConfig.xml 2.写一个po类 和映射文件User.xml(中的namespace=“名 ...
- [转] Understanding Convolutional Neural Networks for NLP
http://www.wildml.com/2015/11/understanding-convolutional-neural-networks-for-nlp/ 讲CNN以及其在NLP的应用,非常 ...
- 利用Linux系统生成随机密码的10种方法【转】
Linux操作系统的一大优点是对于同样一件事情,你可以使用高达数百种方法来实现它.例如,你可以通过数十种方法来生成随机密码.本文将介绍生成随机密码的十种方法. 1. 使用SHA算法来加密日期,并输出结 ...
- python 中@ 的用法【转】
这只是我的个人理解: 在Python的函数中偶尔会看到函数定义的上一行有@functionName的修饰,当解释器读到@的这样的修饰符之后,会先解析@后的内容,直接就把@下一行的函数或者类作为@后边的 ...
- 在VC中改变TAB顺序的方法
用VC来写MFC程序的时候,多数情况下,会发现TAB顺序和预期的顺序不一致,那么这时就有必要重新调整TAB顺序, 来适应我们所写的程序. 调整TAB顺序的方法有两种: 1.在当前的界面或对话框下按“C ...
- codeforces 412div.2
A CodeForces 807A Is it rated? B CodeForces 807B T-Shirt Hunt C CodeForces 807C Success ...
- 码云 Git No network connection
背景 git,好久没用了都.心血来潮还是赶紧熟悉下吧.果不其然,每次要熟悉或开始一个东西,立马就出现问题.本来好好的环境竟然不行了,搞定后感觉应该是换了网络环境的事.这倒次要,主要让我想起了最初学习g ...