//2024.3.7
//指针是用来访问内存的
//指针运算
//指针加1
//int main() {
// int a = 10;
// int* p;
// p = &a;
// return 0;
//}
//p+n 跳过n*sizeof(type)
//下标访问
//int main() {
// int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// int sz = sizeof(arr) / sizeof(arr[0]);
// for (int i = 0; i < sz; i++) {
// printf("%d ", arr[i]);
// }
// return 0;
//}
//指针访问
//int main() {
// int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// int* p = arr;
// int sz = sizeof(arr) / sizeof(arr[0]);
// for (int i = 0; i < sz; i++) {
// printf("%d ", *p);
// p++;
// }
// return 0;
//}
//另一种指针写法
//int main() {
// int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// int* p = arr;
// for (int i = 0; i < 10; i++) {
// printf("%d ", *(p + i));
// }
// return 0;
//}
//数组在内存中是连续存放的,注意是连续的
//指针-指针
//计算前提条件两个指针同一个空间
//得到两个指针之间的元素个数
//不能指针加指针
//类比日期
//数组的地址从小到大
//strlen统计的是字符串中\0之前的字符数
//数组名是数组首元素地址
//int myStrlen(char* str);
//int main(){
// char arr[]="hello world";
// int n=myStrlen(arr);
// printf("%d",n);
// return 0;
//}
//int myStrlen(char* str){
// int count=0;
// while(*str!='\0'){
// count++;
// str++;
// }
// return count;
//}
//换一种写法
//int myStrlen(char* str) {
// char* start = str;
// while (*str != '\0') {
// str++;
// }
// return str - start;
//}
//指针的关系运算
//指针和指针比较大小,比较地址大小
//int main() {
// int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// int sz = sizeof(arr) / sizeof(arr[0]);
// int *p = arr;
// while (p < arr + sz) {
// printf("%d", *p);
// p++;
// }
// return 0;
//}
//野指针
//指针指向位置是不可知的
//没有初始化
//int main(){
// int* p;
// *p=20;
// printf("%p",p);
// //这个p就是野指针
// //非法访问
// return 0;
//}
//一个局部变量不初始化默认是随机值
//int main() {
// int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// int* p = arr;
// for (int i = 0; i <= 10; i++) {
// printf("%d ", *p);
// p++;
// }
// //指针越界
// return 0;
//}
//指针指向的空间释放
//int* test(){
// int a=10;
// return &a;
//}
//int main(){
// int* p;
// //函数调用结束,内存被释放还给了操作系统,此时p是野指针,非法访问,没有访问权限
// printf("%d",*p);
// return 0;
//}
//还有很多场景可能造成野指针
//如何避免
//指针初始化
//明确知道指针指向哪里就指向哪里,不然指向NULL
//int main(){
// int* p=NULL;
// *p=100;
// printf("%d",*p);
// //错误写法
// //这里应该报错
// return 0;
//}
//小心指针越界访问
//指针不在使用后及时置为空指针
//判断指针是否为空
//if(p!=NULL);
//避免返回局部变量的地址
//assert断言 表达式为假会退出程序报错
//#include <assert.h>
//int main(){
// int* p=NULL;
// assert(p!=NULL);
// return 0;
//}
//好处,出现错误会报错指明在哪一行
//关闭assert
//在头文件前定义一个宏 #define NDEBUG
//使用指针解决问题
//非指针不可
//写一个函数交换两个整数的内容
//void swap(int* x, int*y);
//int main() {
// int a = 10;
// int b = 20;
// swap(&a, &b);
// printf("%d %d", a, b);
// return 0;
//}
//void swap(int*x, int*y) {
// int t = 0;
// t = *x;
// *x = *y;
// *y = t;
//}
//地址传递
//函数内部修改主调函数的值,用地址传递
//数组名是首元素地址
//sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小,单位是字节
//&数组名,这里的数组名表示的是整个数组的地址,与数组首元素地址是由区别的
//int main(){
// //arr 首元素地址
// //&arr 整个数组的地址
// return 0;
//}
//类型上不同
//除此之外数组名都是首元素地址
//使用指针访问数组
//int main(){
// //数组在内存中是连续存放的
// //指针加减整数的运算
// return 0;
//}
//arr[i]等价于*(arr+i)
//p[i]等价arr[i]
//数组就是数组,是一块连续的空间
//指针变量是一个变量,大小四个或八个字节,联系是数组名是首元素地址
//可以使用指针访问数组
//[]就是一个操作符
//一维数组的本质
//数组传参的时候,形参是可以写成数组的形式
//但本质上还是指针变量
//数组传参的本质是传递了首元素的地址
//形参访问的数组和实参的数组是同一个数组
//形参数组不会单独创建数组空间的,可以省略数组的大小
//数组大小在传参前计算出来
//int arr[10]等价于int* arr
//本质还是指针
//void print(int* p, int sz);
//int main() {
// int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// int sz = sizeof(arr) / sizeof(arr[0]);
// print(arr, sz);
//
// return 0;
//}
void print(int* p, int n) {
for (int i = 0; i < n; i++) {
printf("%d ", p[i]);
}
}
//冒泡排序
//两两相邻比较
void bubbleSort(int* p, int n);
void bubbleSort(int* p, int n) {
for (int i = 0; i < n - 1; i++) {
int flag=1;
for (int j = 0; j < n - 1 - i; j++) {
if (*(p + j) > *(p + j + 1)) {
int t = *(p + j);
*(p + j) = *(p + j + 1);
*(p + j + 1) = t;
flag=0;
}
}
if(1==flag){
break;
}
}
}
指针1哈哈哈
于 2024-03-08 09:25:41 首次发布
本文详细探讨了指针在C语言中的基本概念,包括指针的定义、指针运算、数组访问方式、指针和数组的区别、内存管理和野指针的防范。此外,还涉及了函数参数传递、排序算法(如冒泡排序)的应用实例。
摘要由CSDN通过智能技术生成