目录
【1】冒泡排序(从小到大)
【2】选择排序
【3】二维数组
【4】指针
【5】指针修饰
【6】大小端
【7】初见二级指针
练习:
【1】冒泡排序(从小到大)
#include <stdio.h>
//数组哪里的\0?自己和字符串区分下
void bubbleSort(int arr[], int size) {
int i, j, temp;
for (i = 0; i < size - 1; i++) {
for (j = 0; j < size - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
// 交换相邻的两个数字
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
int main() {
int arr[] = {5, 3, 8, 2, 1};
int size = sizeof(arr) / sizeof(arr[0]);
int i;
printf("排序前的数组:");
for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
bubbleSort(arr, size);
printf("排序后的数组:");
for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
【2】选择排序
#include<stdio.h>
#define N 5
int main(int argc, char const *argv[])
{
int a[N]={};
int i,j,k,t;
for(i=0;i<N;i++)
scanf("%d",&a[i]);
for(i=0;i<N-1;i++)
{
k=i;
for(j=i+1;j<N;j++)
if(a[k]>a[j])
k=j;
if(i != k)
{
t= a[i];
a[i]=a[k];
a[k]=t;
}
}
for(i=0;i<N;i++)
printf("%d ",a[i]);
printf("\n");
return 0;
}
【3】二维数组
1.格式:
注意 :行数可以省略,列数不能省略
2.元素个数:行数*列数
3.数组名:
int a[][3]={1,2,3,4,5,6};
a:表示第一行的首地址
a+1:表示第二行的首地址
4.初始化:
1)全部初始化:
int a[2][3]={1,2,3,4,5,6};
int a[2][3]={{1,2,3},{4,5,6}};
第一行 第二行
2)部分初始化:未赋初值时值为0
int a[2][3]={1,2,3,4}; //123 400
int a[2][3]={{1,2},{5,6}}; //1 2 0 5 6 0
3) 未初始化:需要分别赋值,未赋初值值为随机值
int a[2][3];
5.内存分配:
a:第一行首地址
a+1:第二行首地址
a[0]:第一行第一列的地址
a[1]:第二行第一列的地址
6.计算大小:
sizeof(数组名)
行*列*数据类型的大小
7.遍历数组:
for循环嵌套,外层行,内层列
for(i=0;i<2;i++)
for(j=0;j<3;j++)
printf("%d ",a[i][j]);
练习:有一个3x4的矩阵(元素值不相同),要求输出其中最大值以及它的行号和列号
//下标替换法
#include<stdio.h>
int main(int argc, char const *argv[])
{
int a[3][4]={15,14,13,2,
5,9,46,56,
12,78,89,13};
int i,j,h=0,l=0;
for(i=0;i<3;i++)
for(j=0;j<4;j++)
if(a[i][j]>a[h][l])
{
h=i;
l=j;
}
printf("max:%d 行号:%d 列号:%d\n",a[h][l],h+1,l+1);
return 0;
}
练习:
猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个,第二天早上又将剩下的桃子吃掉一半,又多吃了一个。
以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了。求第一天共摘了多少。
#include <stdio.h>
int calculatePeaches(int days) {
int peaches = 1;
for (int i = days; i >= 1; i--) {
peaches = (peaches + 1) * 2;
}
return peaches;
}
int main() {
int days = 10;
int totalPeaches = calculatePeaches(days);
printf("第一天共摘了 %d 个桃子。\n", totalPeaches);
return 0;
}
打印杨辉三角形的前十行:重点理清for的查看查看顺序,不要老是整体看,要分开看,一步步看
#include <stdio.h>
int main() {
int numRows = 10;
int triangle[numRows][numRows];
// 初始化杨辉三角形的第一列和对角线为1
for (int i = 0; i < numRows; i++) {
triangle[i][0] = 1;
triangle[i][i] = 1;
}
// 生成杨辉三角形的其他数值
for (int i = 2; i < numRows; i++) {
for (int j = 1; j < i; j++) {
triangle[i][j] = triangle[i-1][j-1] + triangle[i-1][j];
}
}
// 输出杨辉三角形的前十行
for (int i = 0; i < numRows; i++) {
for (int j = 0; j <= i; j++) {
printf("%d ", triangle[i][j]);
}
printf("\n");
}
return 0;
}
【4】指针
1. 概念:
地址:在内存中每个字节都有编号,编号就是地址
指针:指针就是地址
指针变量:存放地址的变量
2. 定义格式:
例子:
int a=5;
int *p = &a;
char ch = 'a';
char * q = &ch;
3. 指针操作符:
&:取地址,取变量的地址
* :取内容,取地址里面的内容
&和*是互逆的,*&a == a &*p == p
4. 初始化:
指针使用前不仅要定义,还要初始化
1)将普通变量的地址赋值给指针变量
int a = 5;
1.int * p = &a;
printf("%d %d\n",a,*p);//a的值 5 5
printf("%p %p\n",&a,p);//a的地址
a = 10; //是地址,就有地址特性
printf("%d %d\n",a,*p);//a的值 10 10
*p = 20;
printf("%d %d\n",a,*p);//a的值 20 20
2.int * p = NULL;
p = &a;
2)将数组的首地址赋值给指针变量
char s[10]="hello";
char * p = s; //p指向hello字符串中字符h
3)将指针变量里面保存的地址赋值给另一个指针变量
int a= 20;
int *p = &a;
int *q = p;
5. 指针运算:
1)算术运算
p++:指针向高地址方向移动一个数据单位,指针的指向发生变化
p--:指针向低地址方向移动一个数据单位,指针的指向发生变化
p+n:访问了高地址方向第n个数据的地址,指针的指向不发生变化
p-n:访问了低地址方向第n个数据的地址,指针的指向不发生变化
两个地址之间的差是相隔元素的个数
2) 关系运算
> < == !=
关系运算比较的是指向地址的高低
指向高地址的指针 大于 指向低地址的指针
int a[5]={};
int *p = &a[1];
int *q = &a[3];
q>p
注:只能在同一个数组间进行地址的比较
6. 指针的大小:
sizeof(指针名)=4(32位操作系统)
总结:
1) 32位操作系统指针大小4字节,64位操作系统指针大小8字节
2) 内存地址是固定的,但是变量地址是不固定的
3) 指针类型根据指针指向空间的数据类型确定的
7. 段错误:Segmentation fault (core dumped)
原因有两条:
1)野指针,没有明确指向的指针
产生原因:1.指针变量没有初始化 2.指针p被free之后没有重新赋值
解决:int * p = NULL;
2)对非法空间赋值
练习:
将字符串转换成整型数字输出。用指针实现
要求:字符串为0-9组成,输出数据为一个整形数
Eg:char s[10]=”123”;printf(“%d\n”,num);//num=123;
#include <stdio.h>
int strToInt(char* str) {
int num = 0;
while (*str != '\0') {
num = num * 10 + (*str - '0');
str++;
}
return num;
}
int main() {
char s[10] = "123";
int num = strToInt(s);
printf("%d\n", num); // 输出:123
return 0;
}
练习:字符串倒置(用指针实现) 如:hello->olleh
#include <stdio.h>
void reverseString(char* str) {
char* start = str;
char* end = str;
char temp;
// 找到字符串的末尾
while (*end != '\0') {
end++;
}
end--; // 指向最后一个非空字符
// 交换字符位置,直到两个指针相遇
while (start < end) {
temp = *start;
*start = *end;
*end = temp;
start++;
end--;
}
}
int main() {
char s[10] = "hello";
reverseString(s);
printf("%s\n", s); // 输出:olleh
return 0;
}
【5】指针修饰
1.const
1)const int a=10; // int const a=10;
a=20; //报错,const修饰a为只读
定义一个指针p指向a,可以通过修改*p改变a的值
2)const int *p; //指针指向的内容不能修改,指针的指向可以修改
int const *p;
int a = 10;
const int *p = &a;
a)*p = 20; //报错,*p被const修饰,不能被赋值
b)int b = 20;p=&b; //√
3)int * const p;//指针的指向不能修改,指针指向的内容可以修改
int a=10;
int b = 20;
int * const p = &a;
a)*p = 20;//正确
b)p= &b;//错误
2.void
void a;//错误
void * p;//任意类型的指针
注意:通过void类型指针取数据时,需要对地址进行强转
(int *)p
【6】大小端
在计算机存储超过一个字节数据的时候,会存在数据存储顺序的不同,分为大端和小端
大端:低地址存放高字节数据,高地址存放低字节数据
小端:低地址存放低字节数据,高地址存放高字节数据
举例:存数据0x12345678,起始地址,0x4000
0x4000 0x4001 0x4002 0x4003
大端: 12 34 56 78
小端: 78 56 34 12
【7】初见二级指针
一级指针:存放变量的地址
二级指针:存放一级指针的地址
格式:存储类型 数据类型 **变量名;
例:
int a= 10;
int * p = &a;
int **q = &p;
访问a的值:
a *p **q
访问a的地址:
&a p *q
访问p的地址:
&p q
练习:
给定一串字符"I love china",实现以单词为单位的逆序,如:"china love i"
思路:可以先全部倒过来:anihc evol i,然后再把每个单词倒过来
#include <stdio.h>
#include <string.h>
int main(int argc, char const *argv[])
{
// char a[32] = "i love China";
char a[32]={};
scanf("%[^\n]",a);
char t;
char *p = a;
char *q = a + strlen(a) - 1;
char *k = NULL;
while (p < q)
{
t = *p;
*p = *q;
*q = t;
p++;
q--;
}
printf("%s\n", a);
p = q = a;
while (*p != '\0')
{
while (*p == ' ')
p++;
q = p; //找单词结尾
while (*q != ' ' && *q != '\0')
q++;
k = q; //暂存空格或\0地址
q--;
while (p < q)
{
t = *p;
*p = *q;
*q = t;
p++;
q--;
}
p=k;
}
printf("%s\n",a);
return 0;
}
用指针将整型组s[8]={1,2,3,4,5,6,7,8}中的值逆序存放
#include <stdio.h>
void reverseArray(int* arr, int size) {
int* start = arr;
int* end = arr + size - 1;
int temp;
// 交换数组元素位置,直到两个指针相遇
while (start < end) {
temp = *start;
*start = *end;
*end = temp;
start++;
end--;
}
}
int main() {
int s[8] = {1, 2, 3, 4, 5, 6, 7, 8};
int size = sizeof(s) / sizeof(int);
reverseArray(s, size);
for (int i = 0; i < size; i++) {
printf("%d ", s[i]); // 输出:8 7 6 5 4 3 2 1
}
return 0;
}