黑马程序员-C学习日记-指针

------- ios培训、 android培训、java培训、期待与您交流! ----------

一.指针

1.内存中最小的单元是字节,每一个字节都有编号,这编号就是指针。

指针:内存地址

有了指针就有了打开这块内存的钥匙,就可以操作这一块内存

2.指针变量:存放内存地址的变量。

3.定义指针:指针所指向数据类型  *指针变量名称

 代码演示:

#include <stdio.h>

int main(int argc ,const char *argv[]{

         int num = 10;

         int *p;

         p = &num;

         *p = 20;

         printf("num=%d\n",num);

    return 0;

}

*  是一个类型说明符,说明定义的变量是指针变量

在不是定义变量的时候, * 是操作符,访问(读、写)指针所指向的那块存储空间。

* 和 & 是一对反操作符 ,*访问指针所指向的存储空间,&是取地址符

4.指针的初始化

注意:(1.)定义而没有初始化的指针,里面存放的是垃圾值,我们称为野指针

(2.)操作野指针会导致程序崩溃,访问你不该访问的存储空间,操作潜在逻辑错误

(3)不可以使用整型常量赋值给一个指针变量,因为内存是系统分配的,不是我们随便取的

4.1 先定义再进行初始化

代码演示:

int num =10;

//定义一个指针变量

int *p;

*p = &num  // 这一步是错误的,p还没有初始化,不能够访问它所指向的存储空间

p = #  // 这一步是正确的,对指针变量p进行了初始化

*p = 20    //访问其指向的存储空间,即变量num的存储空间

4.2定义同时初始化

代码演示:

int num2 = 20; // 定义一个变量

int *p = &num2; // 定义的同时进行初始化,现在指针变量p已经指向了num

*p2 = 40;  // 访问num 所在的存储空间

二.练习

指针的使用场景:

在被调函数中,通过形参来改变主调函数的某个值

由于函数只能有一个返回值,指针可以让函数返回多个值

1.写一个函数交换两个变量的值

错误代码示范:

void swap1(int *num1,int *num2)

{

   int *temp = num1;

   num1 =num2;

   num2 = temp;

}

错误原因:这里仅仅是指针的指向进行交换,并没有改变它所指向存储空间的值

如果不使用指针操作符,那么你操作的都是指针变量本身,与它所指向的存储空间无关

正确代码示范:

void swap1(int *num1,int *num2)

{

   int temp = *num1;

   *num1 =*num2;

   *num2 = temp;

}

2.写一个函数,返回2个数的和、差

 1 #include <stdio.h>
 2
 3 void sumAndMinus(int num1,int num2,int *sum,int *minus)
 4
 5 {
 6
 7    *sum = num1 + num2;
 8
 9    *minus = num1 - num2;
10
11 }
12
13 int main(int argc ,const char *argv[]{
14
15    int a = 10;
16
17    int b = 20;
18
19    int sum,minus;
20
21    //调用函数
22
23    sumAndMinus(a,b,&sum,&minus);
24
25    printf("%d,%d\n",sum,minus);
26
27  return 0;
28
29 }

三.多级指针

四.指针为什么区分类型

所有的指针类型都是占用8个字节的存储空间

1.变量的地址是变量所占存储空间的首地址

2.指针变量仅仅可以存储一个地址编号,如果没有类型,指针就不知道要访问多少个字节的存储空间

3.指针区分类型是为了能正确访问它所指向的存储空间

4.如果通过一个char类型的指针操作一个int类型变量,如果变量值的二进制值超过一个字节,就会导致数据报错

5.如果通过一个int类型的指针操作一个char类型变量,那么就会修改不该修改的内存,造成程序逻辑错误

五.指针与数组

1.指针与一维数组

数组像一个指针:访问数组中的元素,使用数组与使用指向这个数组的指针是等价的

数组不是一个指针:

(1)sizeof(array)!=sizeof(pointer);当一个数组赋值给一个指针变量的时候,那么数组有些信息会丢失,比如数组长度,这种现象称为指针信息遗失

(2)指针的指向可以改变,数组的指向不可以改变array == &array

(3)自己的理解:

num[1] == p[1]

num+1  ==  p+1

nums[1]的本质是*(nums+1)

规律:指针+整数 ==指针中的值 + sizeof(所指向的数据类型)*整数

2.指针与二维数组

(1)指针数组:元素为指针的数组

格式: 指针类型  数组名称[指针元素个数]   int *ps[5];

(2)数组指针:指向数组的指针

指向一维数组的指针   int (*ps)[元素个数];

指向一维数组的指针它是和二维数组相对应

(3)自己的理解

int nums[3][3] = {1,2,3,4,5,6,7,8,9};

pointer = nums;

pointer+1  // +一个其所指向的一维数组长度

nums + 1   // +一个它里面一维数组的长度

nums[1]+1  // +一个一维数组的元素长度

六.指针与函数

1.指针函数:返回值为指针的函数

局部变量的地址不可以作为函数返回值,因为局部变量在函数结束的时候会被系统回收

2.函数指针:指向函数的指针

(1)定义格式:

指针所指向的函数返回值类型 (*函数指针名称)(指针所指向的函数形参列表)

(2)定义步骤:

拷贝所要指向的函数

把函数名称用小括号括起来

在函数名称前面加一个*

函数名称换成指针名称

Ps:函数指针的指向是可以改变的,但必须指向同类型的函数(返回值类型与形参列表都相同)

代码演示:

 1 #include <stdio.h>
 2
 3 int sum(int num1,int num2)
 4
 5 {
 6
 7   return num1+num2;
 8
 9 }
10
11 int minus(int num1,int num2)
12
13 {
14
15   return num1-num2;
16
17 }
18
19 int main(int argc ,const char *argv[]{
20
21    //定义一个函数指针
22
23     int (*p)(int num1,int num2);
24
25     p = sum;// 函数指针p指向了函数sum
26
27    //int rs = p(10,20)
28
29     printf("rs=%d\n",rs);
30
31     p = minus;// 函数指针p指向了函数minus
32
33     rs = p(10,20);
34
35     printf("rs=%d\n",rs);
36
37   return 0;
38
39 }
时间: 2024-10-26 14:27:45

黑马程序员-C学习日记-指针的相关文章

黑马程序员-JAVA学习日记-数组YNPB

黑马程序员学习笔记黑马程序员编程基础数组培训.培训.期待与您交流!数组:是存储同一种数据类型的的集合,也叫容器:特点:是数组中每个元素都有索引从开始:数组的定义式:数据类型数组名数据类型元素个数:数据类型数组名数据类型元素个数:如:数据类型数组名数据类型元素数据类型数组名元素如:如果元素确定就用这一种:数组中有一个属性:获取数组中的元素个数,即数组的长度:中的内存机制:栈:存储局部变量,一般定义在函数内的变量成为局部变量:特点:当内存中数据操作完成后,所占空间会自动释放栈内存堆:是通过创建的实体

黑马程序员-OC学习日记-对象与方法、对象与函数

------- ios培训. android培训.java培训.期待与您交流! ---------- 一.NSString类简介 1.NSString是OC中用来表示字符串的一个类 2.NSString类创建 (1)通过字面量方式创建 NSString * str = @"要努力学习!"; (2)通过对象方法创建 NSString * str1 = [NSString alloc]; str1 = [str1 initWithUTF8String:"今天雾霾好大!"

黑马程序员-C学习日记-字符串

------- ios培训. android培训.java培训.期待与您交流! ---------- 一.系统内存分区 总结: 栈:存放局部变量(函数中定义的变量),内存由系统管理 堆:存放对象,它由程序猿自己申请自己释放,内存需要程序猿自己管理 全局区:存放全局变量与静态变量,由系统管理 常量区:用来存放常量,内存由系统管理,它是只读区 代码区:存放代码的,内存由系统管理,它是只读区 二.定义字符串 1.定义字符串的第一种方式:使用字符数组 char name[] = "sxl";

黑马程序员-C学习日记-结构体

------- ios培训. android培训.java培训.期待与您交流! ---------- 一.局部变量与全局变量 1.局部变量:定义在函数内部的变量以及函数形参称为局部变量 作用域:从定义的那一行开始直到其所在的代码块结束 生命周期:从程序运行到定义那一行开始分配存储空间到程序离开该变量所在的作用域 特点:(1)相同作用域内不可以定义重名变量 (2)不同作用域可以定义重名变量,内部作用域变量可以覆盖外部作用域变量 2.全局变量:函数外部定义的变量 声明: 数据类型 变量名称 定义: 

黑马程序员-C学习日记-数组

------- ios培训. android培训.java培训.期待与您交流! ---------- 一.数组的基本概念 1.数组:用来保存多个相同数据类型的数据的集合 定义变量: 数据类型 变量名称 定义数组: 数据类型 数组名称[元素个数] 二.数组的多种初始化方式 1.数组只有定义了才能进行初始化,只有初始化才能使用 数组遍历:取出数组中的每一个元素看一下 代码演示: 1 #include <stdio.h> 2 3 int main(int argc ,const char *argv

黑马程序员Java学习日记之 Java-其他类型

OK , 就绪, 第一篇博客开撸 ~ android培训.java培训.期待与您交流! 先听了毕姥爷激情澎湃的其他类型 ,从这里开始入手吧 : (一)System类  System类代表系统类,系统的属性和方法都放在该类.System类是一个final类, 它不能被初始化,,即System类中的属性和方法都是static的,可以直接陪调用.System的成员变量有 out,in, err 即标准输入输出和错误输入(流),常用到的System类的方法有下面几个: a. arraycopy方法 :p

黑马程序员-OC学习日记-继承、多态

------- ios培训. android培训.java培训.期待与您交流! ---------- 一.两个关键字self和super 1.局部变量与成员变量 (1)在方法内部可以定义与成员变量同名的局部变量. 在局部变量作用域内,会覆盖成员变量 (2)如果在方法内部定义了与成员变量同名的局部变量. 通过self访问成员变量,以区别局部变量 (3)全局变量是整个文件共享的,如果在一个方法中修改全局变量,在其他方法中使用这个全局变量都会修改 (4)就近原则: 查找顺序:局部变量  ->  成员变

黑马程序员-C学习日记-函数

------- ios培训. android培训.java培训.期待与您交流! ---------- 一.函数的基本概念 1.函数:完成特定功能的代码块 2函数作用:管理代码的 3.函数优点: 提高代码的可读性 提高代码的可复用性 提高代码的可维护性 4.注意点:函数名不可以重复定义 要给函数起一个有意义的名字 5.函数特点:只有调用才会执行. 函数可以封装代码块 二.定义函数 1.函数定义的格式 返回值类型  函数名称(参数类型 参数名称,参数类型 参数名称,...) { 语句: …… ret

黑马程序员_学习IOS之字典常用的方法

字典是无序的 数组是有序的.字典分为:可变字典和不可变字典  不可变字典对象 NSDictionary * dict = [[NSDictionary alloc]initWithObjectsAndKeys:@"one",@"1",@"two",@"2",@"three",@"3",@"four",@"4", nil]; //value = ke