黑马程序员---c语言基础---数组、指针

时间:2021-03-07 00:24:03

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

一、一维数组

1.定义:是一组相同类型数据的有序集合

2.初始化:int a[3] = {2,5,34};或者int a[3] = {19,3};或者int a[ ] = {23,3,54};或者int a[3] = {[0]=1,[1]=23} ;

3.一维数组的储存方式:

1)计算机给数组分配一个连续的储存空间

2)数组名即为数组的地址,首个元素地址也为数组地址

3)每个元素占用相同字节数

4)元素之间地址连续

4.数组元素的使用以及遍历

我们通常通过“数组名[下标]”的方式来访问数组元素,而数组元素的遍历通常用for循环:

#include <stdio.h>

int main(int argc, const char * argv[]) {

    int a[10]={1,2,3,4,5,6,7,8,9,10};
    
    for (int i = 9;i >= 0;i--){          //顺序遍历和逆序遍历改动for循环即可
    printf("%d  ",a[i]);                 //按下标打印每一个元素
    }
        return 0;
}
5.一维数组应用

1)数组长度计算:int len = sizeof(a)/sizeof(数据类型)

2)冒泡排序:分大数下沉法和小数上浮法,核心内容是每次都比较相邻两个元素大小,再按要求交换元素值

大数下沉法:

for (int i = len; i > 0; i--) {              //外层循环控制数据长度,每循环依次最后一个数为当前最大,不需再比较
        for (int j = 0 ; j < i-1; j++) {
            if (a[j]>a[j+1]){                //从第1个数开始比较,若前数比后数大,则交换元素值
                int temp; 
                temp = a[j];
                a[j] = a[j+1];
                a[j+1] = temp;
            }
        }
    }

3)选择排序:与冒泡排序不同,这里是选定一个元素作为参照,依次比较其他元素,再按要求做值交换
for (int i = 0; i<len;i++) {                //依次将元素作为参照,直到最后一个元素
        for (int j = len-1; j>i; j--) {       
            if (a[i]>a[j]) {                //以第i个元素作为基准,与后面元素做大小比较,最后将最小值放到a[i]
                int tem;
                tem = a[i];
                a[i] = a[j];
                a[j] = tem;
            }
        }
    }
4)折半查找:每次都与中间元素作比较,来判断所找元素的区域(注:这里数组已经排序)
while (low<=high) {

            mid = (low+high)/2;            //每循环一次,中间元素下标更新一次

            if (key<a[mid]) {              //若所找元素比中间元素小,则在前半区,最大下标变为中间元素前一个
                high = mid-1;
            }
            else if (key>a[mid]){          //若所找元素比中间元素大,则在后半区,最小下标变为中间元素后一个
                low = mid+1;
            }
            else{
             printf("找到该元素位置了");      //元素与中间元素值相等,该元素即为所找的元素
            }                              
    }

二、二维数组

1.定义:是特殊的一维数组,可以把它看做元素为数组的数组,a[2][3]表示数组有2行3列

2.初始化:int a[2][3] = {{2,4,534},{45,34,6}};其他初始化方法类似一维数组

3.存储结构:

1)是一个连续的储存空间

2)数组名即为数组地址

3)按照每行每行一次储存

4)所有元素占用相同字节数

5)每个相邻元素的地址是连续的

4.二维数组元素的使用及遍历

二维数组的元素访问也是通过下标访问,如a[1][2]则表示第二行第3个元素,数组的遍历则通过两层循环实现:

int score[3][5]={80,61,59,86,75,76,65,63,87,77,92,71,70,90,85};
    
    for (int i = 0; i<3; i++) {             //外层循环控制行数
        for (int j = 0; j<5; j++) {         //里层循环控制列数
            printf("%d  ",score[i][j]);     //打印i行j列的元素
        }
        printf("\n");
    }

三、字符数组与字符串数组

1.字符数组:每个元素都为字符,实际上存放的是一个字符串,如char a[20] = "xiaoming"

2.字符串数组:每个元素都为字符串,实际为一个二维字符数组,如char a[2][10] = {{"jay"},{"jack"};

3.字符串输入输出:C语言中用%s控制字符串的输出,当遇到“\0”时则停止输出,当用%s控制scanf输入时,遇到回车或者空格都会结束输入

4.字符串处理函数:

1)输入:gets(),括号中放字符串需要存放的数组(注:gets可接受空格,且存在数组越界问题)

2)输出:puts(),括号中放输入数组名或数组地址,函数自动换行

3)字符串连接:stract(A,B),需要先导入头文件,作用是将B字符串连接到A字符串尾部(注:A需要有足够长度)

4)字符串拷贝:strcpy(A,B),需要先导入头文件,作用是将B字符串覆盖A字符串(注:A需要有足够长度)

5)字符串大小比较:strcmp(A,B),需要先导入头文件,返回值大于0则A字符串大于B,反之B大于A,等于0则两字符串相等

6)字符串长度计算:strlen(A),计算A字符串长度(注:当字符串为汉字时,每个字符占3个字节)

四、指针

指针是C语言中非常重要的数据类型,没学好指针就相当于没学好C语言,指针其实就是地址

1.普通指针:(注:指针类型应该和指向的数据类型一致)

int a = 3;
int *p;
p = &a;

2.二级指针
int a = 9;
int *p = &a;
int *p1 = &p;
这里的p就是一个二级指针

3.数组指针:即指向数组的指针,存放的地址为一个数组的地址

int a[5] = {2,4,6,34,5};
int p = &a;
(p+i)表示指向第(i+1)个元素的指针

    二维数组指针:

int a[2][3];
int (*p)[3];
P表示指向数组行数的指针,(p+1)表示指向数组的下一行

4.指针数组:即数组存放的元素都为指针,也是地址

int a[2][2] = {1,2,3,4};
int *pa[2] = {a[0],a[1]};
pa[0]存放的元素为第一行的地址,pa[1]存放的元素为第二行的地址

5.字符串指针:即指向字符串的指针

char *p;
p = "adfs";
6.返回指针的函数:即一个函数的返回值为指针
#include <stdio.h>

char* day(int n){                        //定义一个函数作用是根据参数返回星期几

    char *xingqi[] = {"星期一","星期二","星期三","星期四","星期五","星期六","星期日"};
    char *p = xingqi[n-1];               //p指向对应星期数

    return n<8&&n>0?p:"错误";             //函数返回值为指向星期数的指针p
}

int main(int argc, const char * argv[]) {
    
    int a;
    
    printf("请输入一个1到7的整数\n");
    scanf("%d",&a);                       //接收用户输入数字
    
    printf("%s",day(a));                  //调用函数,打印指针指向的内容
    
    return 0;
}
7.函数指针:即指针指向的是一个函数
int sum(int a,int b){        //定义一个求和函数
    return a+b;
}
int jian(int a,int b){        //定义一个求差函数
    return a-b;
}

int (*p)(int ,int);
    p = sum;          //p指向函数sum
    p = jian;         //p指向函数jian