您的位置:首页 > 娱乐 > 明星 > C语言补充:指针的基础理解

C语言补充:指针的基础理解

2024/10/6 16:20:46 来源:https://blog.csdn.net/2302_82004664/article/details/140350427  浏览:    关键词:C语言补充:指针的基础理解

在这里插入图片描述

1.int* 和 char* 的修改字节上的区别及指针的运算

先看两段代码:

int a = 0x11223344;
int* pa = &a;
*pa = 0;
int a = 0x11223344;
char* pa = &a;
*pa = 0;

在这里插入图片描述
在这里插入图片描述
这里我们不难发现对于指针的改变其实是取决于对应的指针类型的,32位环境下char就是一个字节,而int为4个字节

知道了这一点之后我们就可以对指针+/-数实际上就是跳过对应的字节

int main() {int arr[5] = { 1,2,3,4,5 };int sz = sizeof(arr) / sizeof(arr[0]);int* p = &arr[0];for (int i = 0; i < sz; i++){printf("%d", *p);p++;//也可以写成:printf("%d", *(p + i));}return 0;
}

这就是指针加上数字,那么指针-指针有什么意义吗
其实可以类比成日期-日期就能算到中间差几天,那么指针就是中间差的元素数
例如:用char*类型计算字符中间的差值

int my_strlen(char* p) {char* p1 = p;while (*p != '\0'){p++;}return p - p1;//指针-指针
}int main() {char arr[] = "abcdef";int len = my_strlen(arr);printf("%d", len);return 0;
}

2.const的对变量和指针的作用

int main() {const int n = 10;//n = 0;          //err n无法改变//arr[n];         //err n为常量就不会报错int* p = &n;*p = 0;printf("%d", n);  //n=0return 0;
}

由此我们可以看出对于变量的限制并不会使变量改变成常量,而且可以通过指针的方式让变量改变

而对指针的修饰有两种

int main() {int a = 0;int b = 10;const int* p = &a;p = &b;//*p = 10;       //errint* const ps = &a;//ps = &b;      //err*ps = 10;return 0;
}

3.传值调用和传址调用

传值调用:仅仅使用值

void Swap(int x, int y) {int z = 0;z = x;x = y;y = z;
}int main() {int a = 10;int b = 20;printf("交换前:%d,%d\n", a, b);//交换前:10, 20Swap(a, b);printf("交换后:%d,%d\n", a, b);//交换后:10, 20return 0;
}

传址调用:要对传过去的值进行修改

void Swap(int* x, int* y) {int z = 0;z = *x;*x = *y;*y = z;
}int main() {int a = 10;int b = 20;printf("交换前:%d,%d\n", a, b);//交换前:10, 20Swap(&a, &b);printf("交换后:%d,%d\n", a, b);//交换后:20,10return 0;
}

4.数组名的理解

数组名一般就是首元素的地址除了以下几种情况:

  1. sizeof(数组名) 表示整个数组的地址
  2. &(数组名) 取出的是整个数组的地址
    在这里插入图片描述
    知道了一点就可以进行输入函数了
int main() {int arr[10];int* p = arr;int sz = sizeof(arr) / sizeof(arr[0]);for (int i = 0; i < sz; i++) {scanf("%d", p + i);}for (int i = 0; i < sz; i++) {printf("%d ", *(p + i));//arr[1]=*(arr+1) -->  *(p + i)=p[i]}return 0;
}

这里以将arr[1]和*(arr+1)认为是一致的那我们就可以认为平时的传数组调用了

void size_arr(int arr[]) {                 //void size_arr(int* arr)int sz = sizeof(arr) / sizeof(arr[0]); //1printf("%d", sz);
}int main() {int arr[] = { 1,2,3,4,5,6,7,8,9 };int sz = sizeof(arr) / sizeof(arr[0]);printf("%d\n", sz);                    //9size_arr(arr);return 0;
}

5.冒泡排序

int main() {int arr[8] = { 7,6,5,4,3,2,1,0 };int sz = sizeof(arr) / sizeof(arr[0]);for (int i = 0; i < sz - 1; i++)        //将一个数据放到正确的位置,最坏的情况要跑sz-1次{for (int j = 0; j < sz - 1 - i; j++)//sz-1是为了交换sz-1个数据,-i是为了减去已经放置好的数据{if (arr[j] < arr[j + 1]){int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;}}}for (int i = 0; i < sz; i++){printf("%d ", arr[i]);}return 0;
}

第一个循环:将一个数据放到正确的位置,最坏的情况要跑sz-1次
第二个循环:sz-1是为了交换sz-1个数据,-i是为了减去已经放置好的数据
这里可以优化:

int main() {int arr[8] = { 7,6,5,4,3,2,1,0 };int sz = sizeof(arr) / sizeof(arr[0]);for (int i = 0; i < sz - 1; i++)//将一个数据放到正确的位置,最坏的情况要跑sz-1次{int flag = 1;//假设已经有序for (int j = 0; j < sz - 1 - i; j++)//sz-1是为了交换sz-1个数据,-i是为了减去已经放置好的数据{if (arr[j] < arr[j + 1]){int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;flag = 0;//交换就证明无序}}if (flag == 1){break;}}for (int i = 0; i < sz; i++){printf("%d ", arr[i]);}return 0;
}

6.qsort函数的使用

我们使用排序是不一定总是在比较整形,如果是字符串类型或结构体那么就可以使用到去qsort函数了

使用时我们要知道4个参数:

  1. void* base 指针指向要排序的第一个数组
  2. size_t num base指向的待排序的元素数组个数
  3. size_t size base指向待排序元素的大小
  4. int * (compar) (const void *, const void *) 函数指针指向的是如何比较元素的函数
    函数的返回值:
    p1>p2 返回>0的数
    p1=p2 返回0
    p1<p2 返回<0的数
int Cmp_int(const void* e1, const void* e2)//e1为第一个要比较元素地址,e2为第二个要比较元素的地址
{//p1>p2 返回>0的数//p1=p2 返回0//p1<p2 返回<0的数if (*(int*)e1 > *(int*)e2)return 1;else if (*(int*)e1 == *(int*)e2)return 0;elsereturn -1;
}void test01()
{int arr[] = { 9,8,7,6,5,4,3,2,1,0 };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(int), Cmp_int);for (int i = 0; i < sz; i++){printf("%d ", arr[i]);}
}int main() {test01();return 0;
}

在这种情况的返回值可以改成为

int Cmp_int(const void* e1, const void* e2)
{return *(int*)e1 - *(int*)e2;
}void test01()
{int arr[] = { 9,8,7,6,5,4,3,2,1,0 };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(int), Cmp_int);for (int i = 0; i < sz; i++){printf("%d ", arr[i]);}
}int main() {test01();return 0;
}

对于其他的结构也是这样,下面为结构题的示例,分别可以按照自己想来的进行排序

struct Stu
{char name[20];int age;
};int Cmp_struct_by_name(const void* p1,const void* p2)
{return strcmp(((struct Stu*)p1)->name, ((struct Stu*)p2)->name);
}int Cmp_sturct_by_age(const void* e1, const void* e2)
{return ((struct Stu*)e1)->age - ((struct Stu*)e1)->age;
}void test02() {struct Stu arr[3] = { {"zhangsan",20},{"lisi",35},{"wangwu",18} };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), Cmp_struct_by_name);
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com