基于Linux学习 C语言——基础 DAY11

 一、指针

1.1 指针的运算

i)算数运算

int a=100;

int *p=&a

+

*p+n/a+n

先取值,对值+n

p+n/ &a+n

向高字节方向偏移n倍数据类型字节大小

*(p+n)

向高字节方向偏移n倍数据类型字节大小,在取值

&p+n

向高字节方向偏移n倍指针字节大小n

-

*p-n/a-n

先取值,对值-n

p-n/ &a-n

向低字节方向偏移n倍数据类型字节大小

*(p-n)

向低字节方向偏移n倍数据类型字节大小,在取值

&p-n

向低字节方向偏移n倍指针字节大小n

p-q

连续空间,连个指针做减法计算之间元素的个数

++

(&a)++\++(&a)

报错,一个变量的地址时常量

p++/++p

向高字节方向偏移1数据类型字节大小

++(*p) /++*p

先取值,对值加1

*++p

先向高地址偏移1个数据类型大小,在取值

(*p)++

先取值,先运算,在自增1

*p++

先p++结合,但是++后缀运算,先取值,对地址向高字节方向偏移1个数据类型大小

*(p++)

先p++结合,但是++后缀运算,先取值,对地址向高字节方向偏移1个数据类型大小

--

类似++运算

ii)赋值运算

= += -=

p+1 只是参与运算,不改变p自身的指向

p=p+1,参与运算,改变p的指向

=

int *p=&a

指针p指向a的地址,把a的地址赋值给p

+=

p+=2

p改变指向,向高字节方向偏移2个数据类型字节大小

-=

p-=2

p改变指向,向低字节方向偏移2个数据类型字节大小

iii)关系运算

> >= <

>

大于

p>q

>=

大于等于

p>=q

小于

p

小于等于

p

==

等于

p==q

!=

不等于

p!=q

使用指针实现字符串逆转

#include<stdio.h>
#include<string.h>
int main() {
	char arr[127] = "";
	scanf("%126s", arr);
	char* p = arr;
	int len = strlen(arr);
	char *q= arr + len - 1;
	int temp;
	while (p <  q) {
		temp = *p;
		*p = *q;
		*q = temp;
		p++;
		q--;
	}
	printf("%s\n", arr);
	return 0;
}

1.2 值传递和地址传递

 

 

1.3 指针和一维数组 

指针指向数组时直接指向数组名即可,等同于指向数组首元素的地址

int arr[3];
int *p=arr;//int *p=&arr[0]

值:arr[i] -->*(arr+i) -->*(&arr[0]+i)

p[i] --->*(p+i) --->*(&p[0]+i)---->*p++

地址: &arr[i] -->arr+i --->&arr[0]+i

&p[i] --->p+i ---->&p[0]+i --->p++

指针实现冒泡排序&简单选择排序

#include <stdio.h>
#include<string.h>
#define _CRT_SECURE_NO_WARNINGS
void bubble_up(int *p,int len) {
	for (int i = 0; i < len - 1; i++) {
		for (int j = 0; j < len - 1 - i; j++) {
			if (*(p + j) > (*(p + j + 1))) {
				int temp = *(p + j);
				*(p + j) = *(p + j + 1);
				*(p + j + 1) = temp;
			}

		}
	}
	for (int k = 0; k < len; k++) {
		printf("%d ", *(p + k));
	}
	printf("\n");
}


void simple_selection_down(int* p, int len) {
	int max = 0;
for (int i = 0; i < len - 1; i++) {
		max = i;
		for (int j = i+1; j < len; j++) {
			if (*(p + max) < *(p + j)) {
				max = j;
			}
		}
		if (max != i) {
			int temp = *(p + max);
			*(p + max) = *(p + i);
			*(p + i) = temp;
		}
	}
	for (int k = 0; k < len; k++) {
		printf("%d ", *(p + k));
	}
}

int main() {
	int arr[10] = { 0 };
	int len = sizeof(arr)/sizeof(arr[0]);
	for (int m = 0; m < len;m++) {
		scanf("%500d", arr+m);
	}
	int* p = arr;
	printf("冒泡:\n");
	bubble_up(arr, len);
	printf("简单选择:\n");
	simple_selection_down(arr, len);
	return 0;
}

1.4 指针和字符串

 计算机中分为这几个区,字符串数组之所以能修改,是因为在栈区定义了个数组,复制静态只读取中的字符串,然后在栈区中操作,如果只是指针指向的字符串不能修改!!!但可以读取

字符串连接        数组和指针两种方式

#if 1
void my_strcat(char* dest, char* src) {
	while (*dest != '\0') {
		dest++;
	}
	int i= 0;
	while (*(src+i)) {
		*(dest+i)= *(src+i);
		i++;	
	}	
}
#endif
#if 0
    void my_strcat(char *dest,char *src)
    {
        int i=0
        for(i=0;dest[i]!='\0';i++);
        for(int j=0;src[j]!='\0';j++)
        {
            dest[i++]=src[j];        
        }
        dese[i]='\0';
    }
#endif

作业

1.

 错误在于char型数组string大小只有10字节,但是指针str1将11字节的字符串给他,发生越界

2.

 错误在于将6字节的hello\0放入1字节大小的a中,导致缓冲段溢出

3.

 错误在于指针s指向的是字符串常量,而字符串常量是在静态只读段的,只能读取不能修改

4.

 只能计算0-99的和,在i==100时无法进入循环。未初始化指针MyData,对野指针操作会导致程序崩溃。初始化时sum没清零,之后是随机值。MyData在第一个循环之后已经越界到后面的地址了,第二个循环没在0的地址,再++会越界到另一片内存上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值