C语言初级阶段7——指针1

地址与指针

1.地址:数据在内存中的存储位置编号,是一个常量。

2.指针:指针的本质就是地址。

指针变量的定义和声明

1.指针变量:存储的数据是地址。

2.定义方法:类型*标识符

3.得到变量的地址:&

4.指针变量取了谁的地址,就指向谁。

5.*的作用:指针变量的标志

6.*:取内容,解引用

7.指针变量所占内存:一律占四个字节内存

8.注意:定义指针的时候,要马上给指针变量赋值,防止出现野指针(没有任何指向)。

9.NULL:空

10.数组名本身就表示是这个数组的首地址。

11.p += 8;指针的偏移。

12.指针也是有类型的,指针的类型就是定义的时候 类型*变量

13.产生野指针的几种情况

(1)定义一个指针变量时没有初始化

如:int *p;

都知道我们在定义一个非指针的变量时如果没有初始化,则这个变量的值是随机的(如:int a;)

指针变量同样如此,指针变量的随机值的意思就是说他指向的位置是随机的

(2)动态开辟的内存空间在使用完后调用free函数释放掉这段内存空间,却没有将对应的指针职位NULL。虽然开辟的空间被释放掉但指针依旧存在。

如:int func()

{

int *p = malloc(sizeof(int));

free(p);//没有将p值为NULL的操作

}

(3)对指针的操作已经超出了指针变量的作用域

比如通常我们实现了一个函数,该函数里创建了一个指针变量,而函数结束时最终返回这个指针变量,但是函数调用结束后,该函数的函数栈帧就会被销毁,所以返回的这个指针变量所指向的空间已经被释放了,因此这个指针变量指向的空间就变成了随机的。

14.野指针的危害

(1)指向不可访问的地址

危害:触发段错误。

(2)指向一个可用的,但是没有明确意义的空间

危害:程序可以正确运行,但通常这种情况下,我们就会认为我们的程序是正确的没有问题的,然而事实上就是有问题存在,所以这样就掩盖了我们程序上的错误。

(3)指向一个可用的,而且正在被使用的空间

危害:如果我们对这样一个指针进行解引用,对其所指向的空间内容进行了修改,但是实际上这块空间正在被使用,那么这个时候变量的内容突然被改变,当然就会对程序的运行产生影响,因为我们所使用的变量已经不是我们所想要使用的那个值了。通常这样的程序都会崩溃,或者数据被损坏。

15.避免方法

(1)定义一个指针变量时一定记得初始化

(2)动态开辟的内存空间使用完free之后一定将对应的指针置为NULL

(3)不要在函数中返回栈空间的指针和引用

(4)注意在使用时对指针的合法性的判断

#include<stdio.h>
int main() {
int a = 10;
float b = 1.1f;
int* p = &a;
return 0;
}
#include<stdio.h>
int main() {
int a=10, b=20, c=30;
int* p1, * p2, * p3;
p1 = &a;
p2 = &b;
p3 = &c;
printf("%d\n", *p1);
int*a1=NULL;
float*a2=NULL;
double*a3=NULL;
char* a4;
printf("%d\n%d\n%d\n%d\n", sizeof(a1), sizeof(a2), sizeof(a3),sizeof(a4));
printf("%d\n%d\n%d\n%d\n",sizeof(*a1), sizeof(*a2), sizeof(*a3), sizeof(*a4));
return 0;
}
#include<stdio.h>
void fun(int* x, int* y)
{
*x = 3;
*y = 0;
}
int main() {
int a = 10, b = 20;
fun(&a, &b);
printf("%d\n%d\n", a, b);
return 0;
}
#include<stdio.h>
int main() {
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
for (int i = 0; i < 10; i++)
{
printf("%p\n", &arr[i]);
}
int *p = arr;
printf("%d\n", *p);
p += 8;//等价于p = &arr[9]
printf("%d\n", *p);
return 0;
}
#include<stdio.h>
int main() {
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
for (int i = 0; i < 10; i++)
{
printf("%p\n", &arr[i]);
}
int *p = arr+4;//指针的偏移
printf("%d\n", *p);
return 0;
}
#include<stdio.h>
#include<string.h>
int main() {
//常量字符串
const char * p1 = "Hello World";//正常可以去掉const但是VS2022需要加不然报错
printf("%d\n", sizeof(p1));
printf("%d\n", strlen(p1));
p1 += 4;
printf("%c\n" , *p1);
return 0;
}
#include<stdio.h>
int main() {
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
double* p2 = (double*)&arr[0];
p2++;
printf("%d\n", *((int*)p2));
char* p4 = (char*)&arr[0];
p4 += 4;
printf("%d\n", *((int*)p4));
printf("%d\n", *((int*)p2));
return 0;
}

C语言初级阶段7——指针1的更多相关文章

  1. Swift3.0语言教程使用指针创建和初始化字符串

    Swift3.0语言教程使用指针创建和初始化字符串 Swift3.0语言教程使用指针创建和初始化字符串苹果的Swift团队花了不少功夫来支持C的一些基础特性.C语言中为我们提供了指针,Swift也不例 ...

  2. C语言中的指针数组

    C语言中的指针数组是什么,像 char *a[]={"ddd","dsidd","lll"}; 这里讲一下注意如果我们使用了a也就是首元素的 ...

  3. 【ZZ】C 语言中的指针和内存泄漏 & 编写高效的C程序与C代码优化

    C 语言中的指针和内存泄漏 http://www.ibm.com/developerworks/cn/aix/library/au-toughgame/ 本文讨论了几种在使用动态内存分配时可以避免的陷 ...

  4. GO语言中的指针

    http://www.tizgrape.com/?p=100 Go语言中的指针语法和C++一脉相承,都是用*作为符号,虽然语法上接近,但是实际差异不小. Go使用var定义变量: var v6 *in ...

  5. 由链表初始化看C语言的二级指针

    先来看C语言创建链表.插入节点和遍历链表的一段代码: #include <stdio.h> #include <stdlib.h> typedef int ElemType; ...

  6. C语言 > 数组和指针

    C语言 数组和指针 const: 关于指针和const需要注意一些规则.首先,把const数据或非const数据的地址初始化为指向const的指针或为其赋值是合法的. 然而,只能把非const数据的地 ...

  7. C语言结构体指针的引用问题

    在写栈的一个应用时遇见这样的一个问题 SqStack s; s->base = (int*)malloc(sizeof(int)*10); 通过这样一个代码引用的时候,会导致程序出现异常 经过一 ...

  8. Go语言基础之指针

    区别于C/C++中的指针,Go语言中的指针不能进行偏移和运算,是安全指针. 要搞明白Go语言中的指针需要先知道3个概念:指针地址.指针类型和指针取值. Go语言中的指针 Go语言中的函数传参都是值拷贝 ...

  9. c语言之函数指针应用

    c语言之函数指针应用 1.函数指针与指针函数 在开始运用函数指针前,我们需要将两个概念即:函数指针与指针函数搞清楚. 函数指针,指明这个一个函数,但返回值为指针类型,语法格式为: 类型名* 函数名A( ...

  10. C语言中的指针笔记

    C语言指针 得到变量的地址 可以使用&运算符找到变量保存在内存中的位置 int x = 1; printf("x的内存地址是"%p\n",&x) %p格式 ...

随机推荐

  1. The Semantics of Constructors——2.3 程序转化语意学

    2.3 程序转化语意学 #include "X.h" X foo() { X xx; return xx; } 一个人可能会对代码做出以下假设: 每次 foo()被调用,就传回 x ...

  2. 百题计划-6 codeforces 651 div2 E. Binary Subsequence Rotation 01序列集合划分,2个队列处理

    https://codeforces.com/contest/1370/problem/E 队列元素以末尾字符为结尾的序列就好了,这里队列里的元素不重要,队列size重要 #include<bi ...

  3. eclipse和sts的版本对应

    https://blog.51cto.com/9534366/2340508 http://www.mamicode.com/info-detail-2298022.html https://gith ...

  4. Fortran 笔记之 继承和聚合

    继承(类扩展)和聚合 参考自Introduction to Modern Fortran for the Earth System Sciences 我们在3.3部分的开头提到过,OOP范式通常会导致 ...

  5. 吴恩达老师机器学习课程chapter02——分类

    吴恩达老师机器学习课程chapter02--分类 本文是非计算机专业新手的自学笔记,高手勿喷,欢迎指正与其他任何合理交流. 本文仅作速查备忘之用,对应吴恩达(AndrewNg)老师的机器学期课程第六章 ...

  6. docker 部署的mariadb数据库备份还原方案

    docker部署下的mariadb数据库备份还原方案 背景:在使用docker部署的mariadb时,我们会将容器内的数据卷挂载到宿主机上,做简单的备份,容器在正常运行和停止的情况下,能快速创建mar ...

  7. (四)REDIS-布隆过滤器及缓存

    (一)布隆过滤器 布隆过滤器(英语,Bloom Filter)是1970年由布隆提出的.它实际是一个很长的二进制数组+多个随机Hash算法映射函数,主要用于判断一个元素是否在集合中. 通常我们会遇到很 ...

  8. MySQL同步部分库注意的问题

    同步部分库或部分库表 复制部分库:replicate_do_db 复制排除部分库:replicate_ignore_db 复制部分表:replicate_do_table 复制排除部分表:replic ...

  9. ABAP 报表的两种下钻功能

    在报表开发中往往会由需求要求跳转,SAP中提供了一些下钻的方式. 这里主要介绍两种 submit 和 call transaction submit 引用的是报表名称,以自开发报表居多 call tr ...

  10. 基于Jenkins实现可腹部回滚的cicd平台

    Jenkins :是一个开源的实现持续集成的工具,可以实施监控持续集成过程中所存在的问题,提供详细的日志文件和提醒功能,还能用图表的形式直观的展示出项目构建的趋势和稳定性 maven:只有在Java项 ...