指针1
复习一下昨天的重点
<!--.选择排序-->
for(int i = 0; i < len - 1;i++){
for(int j = i+1;j < len;j++){
if(nums[i] > nums[j]){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
}
<!--2.冒泡排序-->
for(int i = 0 ; i < len - 1;i++){
for(int j = 0;j < len - 1 - i;j++){
if(nums[j] > nums[j+1]){
int temp = nums[j];
nums[j] = nums[j+1];
nums[j+1] = temp;
}
}
}
- 二维数组的地址和行列计算
- 二维数组的地址 == 二维数组的低地址 == 第0行的地址 == 第0行的低地址 == 第0行第0个元素的地址 == 第0行第0个元素的地址 == 二维数组的名字
- 二维数组的名字 就是一个地址,就是二维数组的地址
- 二维数组的长度 以及 行列计算
- 长度: 二位数组的总字节数 / 单个元素的字节数
- sizeof(二维数组名)/sizeof(单个元素的数据类型)
- 行数: 二维数组的总字节数/ 每一行的中字节数
- sizeof(二维数组名)/ sizeof(二维数组名[0])
- 列数:列数:二维数组一行的总字节数/单个元素的字节数
sizeof(二维数组名[0])/sizeof(单个元素的数据类型)
二维数组与函数
- 当一个二维数组作为函数的参数的时候 会丢失这个二维数组的行数和列数
- 当二维数组作为函数的参数的时候 行可以省略但是要保证实参二维数组的列数必须要和形参二维数组的列数一致
- 只要是二维数组当做函数的参数,那么就必须加2个参数,一个是行数 一个是列数
- 写参数的时候先写行数, 列数 最后写二维数组 燃豆二维数组的列数 用参数的列数来指定
- void printfArr(int rows, int cols,int arr[][cols]);
字符串
- 原理:
- 将字符串数据的每一个字符存储到字符数组中 ,并在后面追加一个‘\0’代表字符串存储完毕
格式
- 1>最基本的方式:
- char name[10] = {‘a’,’b’,’c’,’\0’};
最简单的方式
char name[30] = {“abc”};//看成 字符串 “abc” 是四个字符 分别是’a”b”c”\0’
字符串可见长度:3
字符串实际长度:4
数组的长度: 4一般来说 如果问 一个字符串的长度是多少就是指实际长度
3>最常用的方式:
- char name[] = “abc”;
- 1>最基本的方式:
使用%s输出在字符数组中字符数据
- 使用格式控制符%s 就可以输出存储在字符数组中的字符串数据
- %s的原理
- 从给定的地址开始 一个字节一个字节的输出 ,直到遇到‘\0’ 位置
- %s 有一个缺点
*如果要打印一个字符串中间有’\0’那么遇到事就会停止
从控制台接收一个字符串
* 安全性 : 当你输入的字符串超过定义的数组长度的时候就会报错
* 缺点: 输入的字符串之间不能有空格 如果有会视为 结束
* 字符串的长度计算*
* char name [10] = “marry jack”
*只能一个一个输出直到 ‘\0’结束
int i = 0;
while(name[i] != '\0')
{
i++;
}
printf("%d",i);
// i就是课件字符串的长度
与字符串相关的函数
#include <stdio.h>
puts(): 输出字符串
* 格式:puts(给定的地址/数组名)
* 原理:从给定的地址开始输入 到’\0’结束
* 优点: 自动换行
* 缺点: 不能格式化输出
gets():控制台获取输入的字符串
* 格式:gets(给定的地址/数组名)
* 优点:输入的时候中间可以有空格
* 缺点: 不安全 ,长度超出范围会报错
#include <string.h>
strlen(): 计算字符串的可见长度
* 格式: strlen(数组名)
* 原理: 一个一个数 直到遇到’\0’结束,但是不包括’\0’
* 优点: 方便
* 缺点: 看不见源代码
* strcmp(): 比较两个字符串的大小*
* 格式:strcmp(字符数组1,字符数组2)
* 返回值的正负:
* 如果返回值是正数: 字符数组1大
* 如果返回值是负数: 字符数组2大
* 如果返回值是0: 一样大
* strcpy(): 拷贝字符串*
* 格式: strcpy(字符数组1,字符数组2);
* 吧字符数组2中的数据拷贝到字符数组1中(’\0’也会拷贝)
* 缺点: 字符数组2 的长度一定不能大于字符数组1的长度
strcat(): 链接两个字符数组
* 格式: strcat(字符数组1,字符数组2)
* 把字符数组2链接到字符数组1后面(会覆盖数组1 的’\0’)
* 缺点:如果字符数组1 的数组长度 不够大会报错
* 变量的值与变量的地址*
* 变量在内存中的存储
* 变量的值: 存在内存中的变量的数据
* 变量的地址: 一个变量是由1个或多个字节组成,组成这个变量的所有字节中的低字节地址
* 如何获取变量的地址: &变量名
* 打印地址: 用%p 来打印一个地址
* 什么是指针!!! 指针就是地址地址就是指针*
一个变量用来保存另外一个变量的地址 如果一个指针变量p 存储了另外一个变量的地址 那么我们称这个指针变量 指向了 num变量 存储谁的地址就是 指向了谁
* 指针的用处:可以通过指针变量 间接访问/修改/获取 它所指向的变量中的数据*
* 如何声明一个变量*
- 语法: 数据类型 *指针变量名
- int * p1;
- 定义了一个指针变量,变量名叫p1 说明这个p1变量能存储int型变量的地址
- 不同类型的指针变量,存储对应类型的变量的地址
指针初始化
- 如何初始化指针
int num = 10;
int *p_num = #
- 打印int num 变量的地址
- 直接打印 : printf(“%p”,&num);
- 间接打印 : printf(“%p”,p_num);
练习
* 定义两个int变量, 定义两个指针分别指向这两个变量
int num1 = 10, num2 = 20;
int *p1 = &num1;
int *o1 = &num2;
指针变量的应用
* 如何使用指针变量 操作它所指向的变量的数据
int num = 10;
int *p_num = #
通过p_num指针指间接操作指针指向的变量
*p_num; //这里的 代表解析地址 解析出来就是num变量
打印:printf("%d",*p_num);
赋值: *p_num = 200;
* 野指针*
* 什么是野指针
* 乱指的指针 ,指针变量中存储的值 是一个垃圾值
int num; // 垃圾值
int *p_num;// 垃圾地址
这个指针就是野指针
定义一个指针, 但是没有给他赋初始值,那么这个指针就是野指针
NULL值
int num = 0;// 定义一个变量 如果不知道初始值,给他赋值一个0
int *p_num = NULL;// 如果定义一个变量,不知道初始值是什么,那么就给他一个默认值NULL
*p_num = 50; // 会报错!!!!
* 如果一个指针变量是NULL值,这个时候通过指针变量去访问指向的变量的时候 会报错
* 结论:
* 只要是声明一个指针不知道初始值 那么就给他一个NULL
* 赋的NULL不能访问 只能重新赋值地址
多个指针指向同一个变量
int num = 10;
int *p1 = #
int *p2 = p1;
// p1 和p2 指针都指向了num地址
- 练习
int num1 = 10;// 定义一个num1 变量
int num2 = 20;// 定义num2变量
int *p1 = &num1; // p1指向了 num1 变量
p1 = &num2; // p1 又指向了 num2 变量
*p1 = 30; // 这个时候p1 指向的num2 变量改变成了30;
printf("num1 = %d,num2 = %d",num1,num2);
结果: num1 = 10,num2 = 30
指针作为函数的参数
- 指针作为函数的参数 是地址传递
- 地址传递 在函数内部 如果改变了地址中变量的值, 那么调用者中的变量的值也会一样改变
写一个函数求 数组中的最大值 和最小值
//写一个函数求 数组中的最大值 和最小值
#include <stdio.h>
#include <stdlib.h>
void maxAndMin(int *arr,int len, int *p_Max, int *p_Min);
int main(int argc, const char * argv[])
{
char *namr = "aaaa";
int max = 0;
int min = 0;
int arr[] = {12,31,23,1,24,231,5,245,635,67,3,5412};
int len = sizeof(arr) / sizeof(arr[0]);
maxAndMin(arr,len,&max,&min);
printf("%d,%d\n",max,min);
return 0;
}
void maxAndMin(int *arr, int len, int *p_Max, int *p_Min)
{
*p_Max = INT32_MIN;
*p_Min = INT32_MAX;
for(int i = 0; i < len; i++)
{
if(arr[i] > *p_Max)
{
*p_Max = arr[i];
}
if(arr[i] < *p_Min)
{
*p_Min = arr[i];
}
}
}