【C语言学习笔记】数组、字符串、指针


第一部分 数组
一、数组的基本使用
(1)定义格式:类型 数组名[元素个数];
(2)遍历:按顺序查看数组的每一个元素
(3)使用注意:
1> 如果想在定义数组的同时进行初始化,数组的元素个数必须是常量,或者不写
    a> int ages[5] = {1, 2, 3, 4, 5};
    b> int ages[] = {1, 2, 3};
    c> int ages[‘A’ - 60] = {1, 2, 3, 4, 5};
 2> 如果元素个数是变量,那不能在定义数组的同时进行初始化,需要单独进行初始化 
   
    int count = 3;
    int ages[count];
    //单独初始化
    ages[0] = 8;
    ages[1] = 9;
    ages[2] = 10;
3> 计算数组元素的个数
    int count = sizeof (ages) / sizeof (int);
二、数组的内存存储细节
(1)
    char cs[5] = {‘A’, ‘B’, ‘C’, ‘D’, ‘E’};
    int ages[3] = {10, 19, 23};
【C语言学习笔记】数组、字符串、指针_第1张图片
(2)数组在内存中的存储方式与变量不同,数组寻址方式是由大到小,内存给数组分配了存储空间之后,其中数组元素在内存中存储的方式是由小到大
三、数组和函数
(1)数组作为函数参数,可以省略元素个数
(2)数组作为函数参数,传递是整个数组的地址,修改函数形参中数组元素的值,会影响到外面实参的数组元素的值
(3)数组当做函数参数传递时,会当做指针变量来使用,指针变量在64bit编译器环境下,占据8个字节
(4)数组名是整个数组的首地址
四、二维数组
二维数组是一个特殊的一维数组:它的元素是一维数组。例如,int c [2][2]可以看作由一维数组c[0]和一维数组c[1]组成,这两个一维数组都包含了2个int类型的元素
【C语言学习笔记】数组、字符串、指针_第2张图片
五、课后练习
/*
设计一个函数:将一维整型数组中的元素逆序存放。比如本来是1,3,4,2,逆序存放就变成了:2,4,3,1
 */

#include 

void ni_xu (int a[], int n);

int main(void)
{
    // 定义数组
    int array[] = {1, 3, 4, 2};
    
    // 先输出一次数组内容
    printf("数组为:\n");
    for (int i = 0; i < sizeof(array) / sizeof(int); i++)
    {
        printf("%d ", array[i]);
    }
    printf("\n");
    
    // 经过逆序存放
    ni_xu(array, sizeof(array) / sizeof(int));
    
    return 0;
}

void ni_xu (int a[], int n)
{
    // 把1和2对换,把3和4对换,对换2次
    for (int i = 0; i < n/2; i++)
    {
        int temp = a[i];
        a[i] = a[n-1-i];
        a[n-1-i] = temp;
    }
    printf("数组逆序存放后为:\n");
    for (int i = 0; i < n; i++)
    {
        printf("%d ", a[i]);
    }
    printf("\n");
}




第二部分 字符串
一、利用字符数组来存储字符串
    char name[10] = "jack";
二、字符串的初始化
(1)基本使用
    1> char name[8] = “it”;
    2> char name2[8] = {‘i’, ’t’, ‘\0’};
    3> char name3[8] = {‘i’, ’t’, 0};    //因为\0的ASCII码值是0。
    4> char name4[8] = {‘i’, ’t’, 0, 0, 0, 0, 0, 0};    //因为多余的内存要以0来补齐,所以也能当做字符串
(2)使用注意:
1> 字符串和字符数组的区别:
字符数组:char name5[] = {‘i’, ’t'};数组元素中没有’\0’
2> \0是字符串结束的标志
三、strlen函数:计算字符串长度
(1)计算的是字符数,并不是字数,一个汉字占3个字符数
(2)计算字符串长度时,\0并不包括在内
(3)从某个地址开始数字符的个数,直到遇到\0为止
四、字符串数组
(1)使用场合:需要存储多个字符串的时候
(2)初始化:char names[2][10] = {“jack”, “rose"};

第三部分 指针
一、基本使用
    int a = 10;
    int *p;
    p = &a;    //指针变量p指向了变量a
    *p = 20;    //把20赋值给了a    
(1)格式:变量类型 *变量名;
(2)指针变量就一个作用,只能存储地址,能够根据一个地址值,访问对应的存储空间
(3)指针变量p前面的int,指针变量p只能指向int类型的数据
(4)*的作用:
1> int *p;中的*:仅仅是个象征,说明p是个指针,没有其他特殊含义
2> *p = 20;中的*:间接运算符,访问指针变量p指向的存储空间
二、使用注意:
(1)定义指针的变量类型须和指针变量指向的变量类型一致,不能出现下面的情况:
    //错误写法 
    int *p;
    double d = 10.0;
    p = &d;
    //指针指定数据类型的意义:指针取值的字节数
(2)指针变量只能存储地址,不能出现下面情况
    //错误写法
    int *p;
    p = 200;
(3)指针变量未经初始化,不能拿来使用,容易造成混乱
三、指向指针的指针
(1)int a = 10;
(2)int *p = &a;    //指针变量p指向a
(3)int **p1 = &p;	//指针变量p1指向指针变量p
(4)int ***p2 = &p1;	//指针变量p2指向指针变量p1
四、指针和数组
(1)数组元素的访问方式
    int ages[5];
    int *p;
    p = ages;
说明:数组名就是数组的首地址,也是数组元素的首地址,指针变量p志向了数组的首元素
1> 数组名[下标] ages[1]
2> 指针变量名[下标] p[1]
3> 
     p —> &ages[0]
     p + 1 —> &ages[1]
     p + 2 —> &ages[2]
     p + i —> &ages[i] 
     所以*(p + i)就是访问ages[i]的存储空间
(2)指针变量+1究竟加多少,取决于指针的数据类型
五、指针和字符串
(1)定义字符串
1> 利用数组
    char name[] = “itcast”;
a> 特点:字符串里面的字符是可以修改的
b> 使用场合:字符串的内容不需要经常修改
2> 利用指针
    char *name = “itcast”;
a> 特点:是一个常量字符串,里面的字符不可以修改
b> 使用场合:字符串的内容不需要修改,而且这个字符串是经常使用的
(2)定义字符串数组
1> 以指针数组形式:
    char *name[3] = {“jack”, “rose”, “jake”};
2> 以二维字符数组形式:
    char name2[3][10] = {“jack”, “rose”, “jake”};
六、返回指针的函数
函数定义格式:
char *test ()	//返回一个指针形式的字符串
{
    return “rose”;
}
七、指向函数的指针
double sum (double d, char *s, int a)
{

}
(1)定义指针变量指向sum函数
double (*p)(double, char *, int);
p = sum;    //指针变量p指向sum函数,函数名sum就是函数sum的地址
或者
double (*p)(double, char *, int) = sum;
1> (*p)固定写法,代表指针变量p一定是指向函数的,切记()不能删除
2> p是变量名
3> 左边的double:指针变量p指向sum函数,sum函数返回double类型的数据
4> 右边的():指针变量p指向sum函数,sum函数有3个形参
(2)如何间接调用函数
1> p (5.8, “rose”, 10);
2> (*p) (5.8, “rose”, 10);
八、课后练习
/*
编写一个函数void strlink(char *s, char *t)
 将字符串t连接到字符串s的尾部
*/
#include 

void strlink(char *s, char *t);

int main(void)
{
    // 定义两个字符串
    char str1[20] = "Hello,";
    char str2[] = "World!";
    
    // 把str2复制到str1的后面
    strlink(str1, str2);
    
    printf("%s\n", str1);
    
    return 0;
}

void strlink(char s[], char t[])
{
    // 1.遍历字符串s,找到结尾
    while (*s != '\0')
    {
        s++;
    }
    
    // 2.找到字符串s的结尾,从字符串t的首字符开始复制,直到把'\0'复制过去
    while ((*s = *t) != '\0')
    {
        s++;
        t++;
    }
}
/*
编写一个函数,判断某个字符串是否为回文。
回文就是从左边开始读 和 从右边开始读 都是一样的,比如"abcba"
*/

#include 
#include 

int isHuiWen(char *p);

int main(void)
{
    // 定义字符串
    char *string = "abcba";
    
    // 定义变量保存结果,返回1则是回文,返回0则不是回文
    int result = isHuiWen(string);
    
    if (result)
    {
        printf("%s是回文!\n", string);
    }
    else
    {
        printf("%s不是回文!\n", string);
    }
    return 0;
}

int isHuiWen(char *p)
{
    // 定义指针变量指向字符串的首字符
    char *left = p;
    
    // 定义指针变量指向字符串的末字符
    char *right = p + strlen(p) - 1;
    
    while (left < right)
    {
        // 如果左边字符和右边字符不一样,则不是回文,返回0
        if (*(left++) != *(right--))
        {
            return 0;
        }
    }
    return 1;
}

你可能感兴趣的:(【C语言学习笔记】)