C/C++教程

C语言指针基础编程练习1(指针、地址、基本指针运算、各基本类型数组、一维指针数组、函数传参、数组传址、sizeof的使用注意)

本文主要是介绍C语言指针基础编程练习1(指针、地址、基本指针运算、各基本类型数组、一维指针数组、函数传参、数组传址、sizeof的使用注意),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

运行结果截图(代码在截图下面):

 

 

 

 

 

 

 

 

 

 代码:

#include <stdio.h>
// 不要在include头文件的语句末加分号
#include <string.h>

int getSizeOfDataType(char * dataType)
{
    printf("\ngetSizeofDataType() loading...\n");

    int size;
    if ("char" == dataType)
    {
        size = sizeof(char);
        printf("sizeof(char):%d\n", size);
    }else if ("int"== dataType)
    {
        size = sizeof(int);
        printf("sizeof(int):%d\n", size);
    }else if ("short" == dataType) {
        size = sizeof(short);
        printf("sizeof(short):%d\n", size);
    }else if ("long" == dataType) {
        size = sizeof(long);
        printf("sizeof(long):%d\n", size);
    }else if ("long long int" == dataType)
    {
        size = sizeof(long long int);
        printf("sizeof(long long int):%d\n", size);
    }else if ("float" == dataType) {
        size = sizeof(float);
        printf("sizeof(float):%d\n", size);
    }else if ("double" == dataType) {
        size = sizeof(double);
        printf("sizeof(double):%d\n", size);
    }else if ("int *" == dataType)
    {
        size = sizeof(int *);
        printf("sizeof(int *):%d\n", size);
    }else if ("char *" == dataType)
    {
        size = sizeof(int *);
        printf("sizeof(char *):%d\n", size);
    }else
    {
        size = 0;
        printf("!!!Unknown datatype, please contact IT support team in your company for further fix...\n");
    }

    int getAddressSize = 0;
    printf("sizeof(internalStorageAddressSize):%d\n",sizeof(&getAddressSize));

    printf("getSizeofDataType() finished...\n\n");

    return size;
}

void printCharPointArray( char * arrayName, char * * arr, int length)
{
    // 如果在函数内用sizeof来获得数组长度,会发现数组退化成了指针,获得的只是指针的长度,因此要在函数外计算出数组长度再传进函数里
    printf("\nprintCharPointerArray() loading...\n");
    // 打印指针数组元素
    printf("(char *) array length is: %d\n",length);
    printf("字符串型指针数组有%d个元素\n",length);
    printf("打印指针数组%s:\n", arrayName);
    for(int i = 0; i < length; i++)
    {
        printf("指针数组第%d个元素是%p,", i, arr[i]);
        printf("以指针数组第%d个元素为地址所存储的值是:    %s\n", i, arr[i]);
    }

    printf("printCharPointerArray() finished...\n\n");
}

void printIntPointerArray( char * arrayName, int * * arr, int length)
{
    // 如果在函数内用sizeof来获得数组长度,会发现数组退化成了指针,获得的只是指针的长度,因此要在函数外计算出数组长度再传进函数里
    printf("\nprintIntPointerArray() loading...\n");
    // 打印指针数组元素
    printf("(int *) array length is: %d\n",length);
    printf("整型指针数组有%d个元素\n",length);
    printf("打印指针数组%s:\n", arrayName);
    for(int i = 0; i < length; i++)
    {
        printf("指针数组第%d个元素是%p,", i, arr[i]);
        printf("以指针数组第%d个元素为地址所存储的值是    %d\n", i, *arr[i]);
    }

    printf("printIntPointerArray() finished...\n\n");
}

void printCharArray( char * arrayName, char * arr, int length)
{
    // 如果在函数内用sizeof来获得数组长度,会发现数组退化成了指针,获得的只是指针的长度
    printf("\nprintCharArray() loading...\n");

    printf("Char array length is: %d\n",length);
    printf("字符串型数组有%d个元素\n",length);
    //打印字符串数组元素
    printf("打印字符串数组:%s\n", arrayName);
    printf("打印字符串数组:%s\n", arr);


    printf("printCharArray() finished...\n");
}

void printIntArray(char * arrayName, int * arr, int length)
{
    // 如果在函数内用sizeof来获得数组长度,会发现数组退化成了指针,获得的只是指针的长度
    printf("\nprintIntArray() loading...\n");

    printf("Int array length is: %d\n",length);
    printf("整型数组有%d个元素\n",length);
    // 打印整型数组元素
    printf("打印整型数组%s:\n",arrayName);
    for(int i = 0; i < length; i++)
    {
        printf("%d, ",arr[i]);
    }
    printf("\n");

    printf("printIntArray() finished...\n\n");
}

void printFloatArray(char * arrayName, float * arr, int length)
{
    // 如果在函数内用sizeof来获得数组长度,会发现数组退化成了指针,获得的只是指针的长度
    printf("\nprintFloatArray() loading...\n");

    printf("Float array length is: %d\n",length);
    printf("浮点型数组有%d个元素\n",length);
    //打印浮点数组元素
    printf("打印浮点数组:%s\n",arrayName);
    for(int i = 0; i < length; i++)
    {
        printf("%f, ",arr[i]);
    }
    printf("\n");

    printf("printFloatArray() finished...\n\n");
}

void printDoubleArray(char * arrayName, double * arr, int length)
{
    // 如果在函数内用sizeof来获得数组长度,会发现数组退化成了指针,获得的只是指针的长度
    printf("\nprintDoubleArray() loading...\n");
    printf("Double array length is: %d\n",length);
    printf("双精度型数组有%d个元素\n",length);
    // 打印双精度数组元素
    printf("打印双精度数组:%s\n",arrayName);
    for(int i = 0; i < length; i++)
    {
        printf("%lf, ",arr[i]);
    }
    printf("\n");

    printf("printDoubleArray() finished...\n\n");
}


void getCharArrayCount(char * arr)
{
    int count = 0;

    // 变量必须是左值才能自增,数组表达的是一个固定的地址值,不能自增,所以必须先定义指针变量p指向数组arr,用p来执行指针运算进行自增
    char * p = arr;
    while(*p++ !='\0')
    {
        count++;
    }
    printf("FYI: 地址为 %p 的字符串数组总共有 %d 个字符\n", &arr, count);
}


void arrayElementAddressDistanceTest()
{
    printf("\nArrayAddressDistanceTest() Loading...\n");
    //定义不同数据类型的数组及数组元素
    char c[] = "JohnnyH";
    int  e[6] = {11,22,33,44,55,66};
    float f[6] = {0.1f,0.2f,0.3f,0.4f,0.5f,0.6f};
    double g[6] = {0.1,0.2,0.3,0.4,0.5,0.6};

    /* 小数也可以使用 printf 函数输出,包括十进制形式和指数形式,它们对应的格式控制符分别是:
        %f 以十进制形式输出 float 类型;
        %lf 以十进制形式输出 double 类型;
        %e 以指数形式输出 float 类型,输出结果中的 e 小写;
        %E 以指数形式输出 float 类型,输出结果中的 E 大写;
        %le 以指数形式输出 double 类型,输出结果中的 e 小写;
        %lE 以指数形式输出 double 类型,输出结果中的 E 大写。
     */
    // 输出字符串数组c

    // 输出字符串数组的长度
    char * charDataType = "char";
    char * charArrayName = "c";
    int sizeOfDataType = getSizeOfDataType(charDataType);
    int charArrayLength = sizeof(c)/sizeOfDataType;
    printCharArray(charArrayName,c,charArrayLength);

    // 输出整形数组e
    char * intDataType = "int";
    char * intArrayName = "e";
    sizeOfDataType = getSizeOfDataType(intDataType);
    int intArrayLength = sizeof(e)/sizeOfDataType;
    printIntArray(intArrayName,e,intArrayLength);

    // 输出浮点数组f
    char * floatDataType = "float";
    char * floatArrayName = "f";
    sizeOfDataType = getSizeOfDataType(floatDataType);
    int floatArrayLength = sizeof(f)/sizeOfDataType;
    printFloatArray(floatArrayName, f,  floatArrayLength);

    // 输出双精度数组g
    char * doubleDataType = "double";
    char * doubleArrayName = "g";
    sizeOfDataType = getSizeOfDataType(doubleDataType);
    int doubleArrayLength = sizeof(g)/sizeOfDataType;
    printDoubleArray(doubleArrayName, g, doubleArrayLength);

    // 输出各个数组头4个元素的地址
    // %p表示按十六进制输出数据,如果输出数据不够8位数,则左边补零
    // 不同数据类型的数组元素地址的间隔不同,char间隔1,int间隔4,float间隔4,double间隔8
    printf("c[0] -> %p,   c[1] -> %p,  c[2] -> %p,  c[3] -> %p\n",&c[0],&c[1],&c[2]);
    printf("e[0] -> %p,   e[1] -> %p,  e[2] -> %p,  e[3] -> %p\n",&e[0],&e[1],&e[2]);
    printf("f[0] -> %p,   f[1] -> %p,  f[2] -> %p,  f[3] -> %p\n",&f[0],&f[1],&f[2]);
    printf("g[0] -> %p,   g[1] -> %p,  g[2] -> %p,  g[3] -> %p\n",&g[0],&g[1],&g[2]);

    // 定义字符类型指针变量pe并指向数组e
    int * pe = e;

    //输出字符串数组d的第一元素d[0]、第二元素d[1]、第三元素d[2]的值和地址
    printf("*pe的值是:%d\npe的值是一个地址:%p\n", *pe,e);
    printf("*(pe + 1)的值是:%d\n(pe + 1)的值是一个地址:%p\n", *(pe + 1),(pe+1));
    printf("*(pe + 2)的值是:%d\n(pe + 2)的值是一个地址:%p\n", *(pe + 2),(pe+2));

    printf("ArrayAddressDistanceTest() Finished...\n\n");
}


void pointerAddressTest()
{
    // 定义字符变量a和整型变量f并初始化
    printf("\nPointAddressTest() Loading...\n");
    char c = 'F';
    int b = 123;

    // 指针变量必须初始化,否则会成为野指针。
    // 指针即地址,虽然指针变量存的是地址,但指针变量不等同于指针

    // 用char*定义字符指针变量pa并初始化,这时指针变量pc存储的是变量a的地址,即指针变量pc指向a的地址
    char * pc = &c;
    // 用int*定义整型指针变量pb并初始化,这时指针变量pb存储的是变量b的地址,即指针变量pb指向b的地址
    int * pb = &b;

    // 输出指针变量pa和pb的值
    printf("a的值是: %c\n", *pc);
    printf("f的值是: %d\n", *pb);

    // *pa是指从pa所存的地址(根据指针初始化,pa存的是a的地址)找到a,然后对a的数值进行赋值。
    * pc = 'C';
    // *pb是指从pb所存的地址(根据指针初始化,pb存的是f的地址)找到f,然后对f的数值进行赋值。
    * pb += 1;

    // 输出指针变量pa指向的地址(即a的地址)所存储的值(即a的值),发现已经被修改
    printf("对字符串变量a地址的内存进行赋值,现在a的值是: %c\n", * pc);
    // 输出指针变量pb指向的地址(即a的地址)所存储的值(即a的值),发现已经被修改
    printf("对整形变量b地址的内存进行赋值,现在b的值是: %d\n", * pb);

    /* 输出指针变量的长度(一个指针变量容量有多少个字节),不同的编译系统的指针变量的长度不同。
       64位系统是8字节,32位系统是4字节。
    */
    printf("指针变量pa的长度是: %d\n",sizeof(pc));
    printf("指针变量pb的长度是: %d\n",sizeof(pb));

    // 定义一个整形变量c
    int d = 666;
    //定义个指针变量pc,pc指向c的地址
    int * pd = &d;

    // 输出c的地址
    printf("c的地址是:%x\n", &d);
    // 输出指针变量pc的值,可以发现就是c的地址
    printf("指针变量pc的值是一个地址:%x\n", pd);

    printf("c的值是:%d\n",d);
    // 指针变量pd的值就是d变量的地址,现在对d地址的内存进行赋值,那么变量d的值就被改为233
    *pd = 233;
    printf("用指针变量pc对c地址的内存进行赋值,现在c的值为:%d\n", *pd);

    printf("pointerAddressTest() finished...\n\n");
}


void pointerArrayTest1()
{
    printf("\npointerArrayTest1() loading...\n");

    int b = 55;
    int d = 44;
    int e = 33;
    int f = 22;
    int g = 11;

    // 定义一个整型指针数组
    int *p[5] = {&b, &d, &e, &f, &g};

    // 定义一个整型数组
    int a[5] = {b,d,e,f,g};

    printf("整型指针数组p的值是   %p\n", p);
    printf("整型指针数组p的地址是 %p\n", &(*p));
    printf("整型指针数组p的第一个元素*p[0]的地址是%p\np[0]的值是%p\nb的值是 %d\n", &(*p[0]), p[0], *(&b));
    printf("整型数组a的地址是    %p\na[0]的地址是%p\nb的值是 %d\n", a, &a[0], b);

    int * hello = * p;
    int * world = a;

    // 如果在非main函数内用sizeof来获得数组长度,会发现数组被传址到了函数里就退化成了指针
    // 对函数内的数组用sizeof获得的只是其指针的长度,因此要在数组所在的函数先计算出数组长度再传参到其他函数

    // 用数组传址方式调用函数来输出数组
    char * intPointerDataType = "int *";
    char * intPointerArrayName = "p";
    int sizeOfDataType = getSizeOfDataType(intPointerDataType);
    int intPointerArrayLength = sizeof(p)/sizeOfDataType;
    printIntPointerArray(intPointerArrayName,p,intPointerArrayLength);

    char * intDataType = "int";
    char * intArrayName = "a";
    sizeOfDataType = getSizeOfDataType(intDataType);
    int intArrayLength = sizeof(a)/sizeOfDataType;
    printIntArray(intArrayName,a,intArrayLength);


    printf("当前*hello的值是:%d\n", *hello);
    printf("当前*hello的地址是:%p\n", hello);
    printf("sizeof(hello):%d\n", sizeof(hello));

    // 直接用for循环,打印指针数组p的元素、元素地址、指针自减
    for(int i = 0;i < 5;i++)
    {
        printf("*p[%d]的值是:%d ", i, *p[i]);
        printf("*hello的值是:%d ", *hello);
        printf("*p[%d]的地址是:%p ", i, p[i]);
        printf("指针hello--自减前的值是:%p\n", hello--);
    }

    printf("当前*world的值是:%d\n", *world);
    printf("当前*world的地址是:%p\n", world);
    printf("sizeof(world):%d\n", sizeof(world));

    // 直接用for循环打印整型数组a的元素、元素地址、指针自增
    for(int i = 0;i < 5;i++)
    {
        printf("a[%d]的值是:%d ", i,a[i]);
        printf("*world的值是:%d ", *world);
        printf("a[%d]的地址是:%p ", i, &a[i]);
        printf("指针world++自增前的值是:%p\n", world++);
    }
    printf("\n");
    printf("\npointerArrayTest1() finished...\n");
}

void pointerArrayTest2()
{
    printf("\npointerArrayTest2() loading...\n");

    // 定义一个字符串指针数组str
    char * str = "Continuous attention to technical excellence and good design enhances agility\n";
    // 打印字符串str
    printf(str);
    // 得出字符串数组str的字符个数
    getCharArrayCount(str);

    // 调用函数方式打印字符串str
    char * charDataType = "char";
    char * charArrayName = "str";
    int sizeOfDataType = getSizeOfDataType(charDataType);
    int charArrayLength = sizeof(str)/sizeOfDataType;
    printCharArray(charArrayName,str,charArrayLength);

    // 输出数组str的地址
    printf("字符串数组str的地址是:%p\n",&str);
    // 输出数组的第一个元素的地址,可见就是数组str的地址
    printf("数组str的第一个元素str[0]的地址是:%p\n",&str[0]);

    printf("pointerArrayTest2() finished...\n\n");
}

void pointerArrayTest3()
{
    printf("\npointerArrayTest3() loading...\n");
    //字符数组(指针数组)
    char * pStr[5] = {
            "欲穷千里目",
            "曲项向天歌",
            "疑是地上霜",
            "野渡无人舟自横",
            "Impossible is nothing!"
    };
    int length = 5;
    getCharArrayCount(pStr);

    // 直接用for循环来打印字符串类型指针数组
    printf("字符串类型指针数组pStr的地址是:%p\n", pStr);
    for(int i = 0; i <length; i++)
    {
        printf("%s ",pStr[i]);
    }
    printf("\n");

    // 调用函数传参传址方式打印字符串类型指针数组
    char * charPointDataType = "char *";
    char * charPointArrayName = "p";
    int sizeOfDataType = getSizeOfDataType(charPointDataType);
    int charArrayLength = sizeof(pStr)/sizeOfDataType;
    printCharPointArray(charPointArrayName,pStr,charArrayLength);

    printf("\npointerArrayTest3() finished...\n\n");
}

int main()
{
    printf("main() loading...\n");

    // 指针地址测试
    pointerAddressTest();

    // 数组元素地址和指针的关系
    arrayElementAddressDistanceTest();

    // 指针数组测试一
    pointerArrayTest1();

    // 指针数组测试二
    pointerArrayTest2();

    // 指针数组测试三
    pointerArrayTest3();

    printf("main() finished...\n");

    return 0;
}

这篇关于C语言指针基础编程练习1(指针、地址、基本指针运算、各基本类型数组、一维指针数组、函数传参、数组传址、sizeof的使用注意)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!