c语言指针

#define _CRT_SECURE_NO_WARNINGS//必须放在第一行
#include <stdio.h>
#include <math.h>

/*
* 计算x的y次方,假设x,y都是整数,y是非负整数,不允许使用库函数
* 1.直接循环乘,计算时间复杂度和空间复杂度
* 2.
* 测试数据(1,1000000000)

* 指针就是地址
* 定义指针(地址)变量: 数据类型 * 变量名;例如int *p;
* &变量名:获得该变量的地址,&称为取地址符.例如&a,&b
* 地址(指针)在赋值时类型必须相同
*   *p:访问p所指向的内容,称为间接访问符或者解引用
*/

//课堂练习
//int main()
//{
//    int a = 10;
//    char b = 'A';
//    short c = 20;
//    long long d = 30;
//    float e = 12.5f;
//    double f = 23.4;
//    //输出a,b,c,d,e,f的地址
//    printf("%d\n", &a);
//    printf("%d\n", &b);
//    printf("%d\n", &c);
//    printf("%d\n", &d);
//    printf("%d\n", &e);
//    printf("%d\n", &f);
//
//    return 0;
//}

/*
int main()
{
    char a;
    //int* p1 = &a;//error
    char* p2 = &a;
    short b = 20;
    float c = 12.5f;
    double d = 45.6;
    long long e = 200;
    short* p3 = &b;//p3保存b的地址
    float* p4;
    p4 = &c;//p4保存c的地址
    double* p5 = &d;//p5保存d的地址
    long long* p6 = &e;//p6保存e的地址
    // int* p7 = (int *) & a;

    return 0;
}
*/

int main()
{
    int a = 10;
    int b = 20;
    int* p = &a;//定义一个指针(地址)变量保存地址值
    *p = 100; //a = 100
    p = &b;//p保存b的地址
    *p = 200;//b=200

    return 0;
}

/*
int g_count = 0;

long long Fibon(int n)
{
    g_count++;
    if (n == 1 || n == 2)
        return 1;
    return Fibon(n - 1) + Fibon(n - 2);
}

int main()
{
    for(int i=1;i<20;i++)
    { 
        Fibon(i);
        printf("第%d项,执行%d次\n",i,g_count);
    }
    
    return 0;
}
*/

#define _CRT_SECURE_NO_WARNINGS//必须放在第一行
#include <stdio.h>
#include <time.h>

/*
* 在力扣上实现x的y次方(数值的整数次方)
* 指针大小:在32位平台(x86)为4字节;在64位平台(x64,arm64)为8字节
*/

bool isPalindrome(int x) {
    if (x < 0)
        return false;
    long long tmp = 0;
    int n = x;
    while (x != 0)
    {
        tmp = tmp * 10 + x % 10;//构造新数字
        x /= 10;//丢弃个位
    }
    return tmp == n;
}

//指针(地址)的大小
int main()
{
    printf("%d\n",sizeof(char*));
    printf("%d\n", sizeof(short*));
    printf("%d\n", sizeof(int*));
    printf("%d\n", sizeof(unsigned int*));
    printf("%d\n", sizeof(long*));
    printf("%d\n", sizeof(long long*));
    printf("%d\n", sizeof(float*));
    printf("%d\n", sizeof(double*));
    //printf("%d\n", sizeof(bool));
    
    return 0;
}

//int main()
//{
//    int a = 10;
//    int b = 20;
//    int* p = &a;
//    *p = 100; //a =100;
//    p = &b;
//    *p = 200;//b = 200;
//    int** pp = &p;
//    *pp = &a;//p = &a;
//    **pp = 1000;//a = 1000;
//    *pp = &b;//p = &b;
//    **pp = 2000;//b=2000;
//
//    return 0;
//}

//课堂练习
//int main()
//{
//    int a = 10;
//    int b = 20;
//    int c = 30;
//    int* p1 = &a;//指针p1保存a的地址
//    int* p2 = &b;//指针p2保存b的地址
//    int* p3 = &c;//指针p3保存c的地址
//    *p1 = *p2 + *p3;//利用p1,p2,p3实现 a=b+c
//    printf("%d\n",*p1);//利用p1,输出a的值
//
//    *p2 = *p1 * *p3;//利用p1,p2,p3实现 b=a*c
//    printf("%d\n",*p2);//利用p2,输出b的值
//
//    *p3 += 100;//利用p3实现 c=c+100
//    printf("%d\n",*p3);//利用p3,输出c的值
//
//    return 0;
//}

//课堂练习
//int main()
//{
//    int a = 10;
//    int b = 20;
//    int c = 30;
//    int* p = &a;
//    *p = 100;//通过p,将a的值修改为100
//    p = &b; *p = 200;//通过p,将b的值修改为200
//    p = &c; *p = 300;//通过p,将c的值修改为300
//    printf("%d,%d,%d\n",a,b,c);
//
//    return 0;
//}

//int main()
//{
//    int a = 10;
//    int b = 20;
//    int *p = &a;
//    int* q;
//    q = &b;
//    *p = 100;//a = 100
//    *q = 200;//b = 200
//    int **pp=&p;
//    int** qq;
//    qq = &q;
//    **pp = 1000;//*pp == *(*pp)==*p==a, a = 1000;
//    **qq = 2000;//b = 2000;
//
//    return 0;
//}

//计算x的y次方.假定y>=0
//long long Mypow1(int x, int y)//O(y),O(1)
//{
//    long long tmp = 1;
//    for (int i = 0; i < y; i++)
//    {
//        tmp *= x;
//    }
//    return tmp;
//}
//
//long long Mypow(int x, int y)//O(logn),O(logn)
//{
//    long long tmp;
//    long long a;
//    if (y == 0)
//        return 1;
//    if (y == 1)
//        return x;
//    a = Mypow(x, y / 2);
//    if (y % 2 == 0)//偶数
//        tmp = a * a;
//    else
//        tmp =  a * a * x;
//        
//    return tmp;
//}
//
//int main()
//{
//    //for(int i=0;i<=10;i++)
//    //    printf("%lld\n",Mypow(2,i));
//    clock_t c1 = clock();
//    Mypow1(1,1000000000);
//    clock_t c2 = clock();
//    printf("循环时间:%d\n",c2-c1);
//    Mypow(1, 1000000000);
//    clock_t c3 = clock();
//    printf("递归时间:%d\n", c3 - c2);
//
//    return 0;
//}

#define _CRT_SECURE_NO_WARNINGS//必须放在第一行
#include <stdio.h>

/*
* 局部变量:定义在函数内部的变量,包括形参.只在函数内部有效,默认值为随机值
* 全局变量:定义在函数外部的变量,整个文件都能使用
* 1字节(Byte,B)=8位(bit,b)
* 1个16进制为4个位,2个16进制数字为1字节
* 指针: 就是地址
*   &变量名:取地址符,例如&a,&b,&p
*   定义指针(地址)变量,int *p = &a;//定义一个int指针(地址)变量
*   *p:解引用,到达p所指向的内容  ,即a
*   *p = 100;等同 a = 100;
* 野指针:悬挂指针,你没有访问权限的地址
* 总结:一个函数想修改另一个函数的值,必须1.传指针;2.解引用
* NULL:无效指针,说明当前指针不能使用
* 一维数组数组名arr表示整个数组:
*    1.在定义数组的同一个函数中,sizeof(arr)表示求整个数组的字节数
*    2.在定义数组的同一个函数中,&arr+1表示加整个数组字节数
*    其它情况arr都表示数组第一个元素的地址
* 指针和数组:
* 数组作为参数传递,需要传数组的首地址还必须传数组的长度
* 求数组arr长度公式:sizeof(arr)/sizeof(arr[0]),注意arr不能使用形参

*/
//void Show(int arr[10])//10是一个无效的值,迷惑
//void Show(int arr[])//int *
void Show(int *arr,int len)
{
    //sizeof(arr) / sizeof(0);//不能使用
    for (int i = 0; i < len; i++)
        printf("%d ",arr[i]);
    printf("\n");
}

void Fun(int arr[10])//笔试经常出现 (arr是指针)
{
    printf("%d\n",sizeof(arr));// 4(32位平台),8(64位平台)
}


int main()
{
    //int arr[] = {1,2,3,4,5,6,7,8,9,10,11,12};
    int arr[] = { 1,2,3,4,5,6,7,8 ,9,10,11,12};
    Show(arr,sizeof(arr)/sizeof(0));//arr只是首元素的地址,int *
    Fun(arr);
    //利用指针遍历数组
    //方法1
    /*int i = 0;
    for (int* p = &arr[0]; i < sizeof(arr) / sizeof(arr[0]); ++p,++i)
    {
        printf("%d ",*p);
    }*/

    //方法2
    //int i = 0;
    //for (int* p = &arr[0]; i < sizeof(arr) / sizeof(arr[0]); i++)
    //    printf("%d ",*(p+i));
    
    //方法3
    //int *p = arr;//arr等同 &arr[0]
    //for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
    //    printf("%d ",p[i]);

    //printf("%d\n",sizeof(arr));
    //printf("%d,%d\n",&arr,&arr+1);//

    return 0;
}

//void Fun(int* p)
//{
//    p = NULL;
//}

//todo 思考题
//int main()
//{
//    int a = 10;
//    int* p = &a;
//    //p = NULL;
//    Fun(p);
//    printf("%d\n",*p);//崩溃,不能对NULL解引用
//    //1.为什么不崩溃,2,如何改就崩溃
//
//    return 0;
//}

//void Fun(int *x1,int *x2)//x1,x2输出参数,在工作使用频繁
//{
//    *x1 = 10;
//    *x2 = 20;
//}
//int main()
//{
//    int a;
//    int b;
//    Fun(&a,&b);
//    printf("%d,%d\n",a,b);
//
//    return 0;
//}
//void Myscanf(int *x)
//{
//    *x = 10;
//}
//int main()
//{
//    int a = 0;
//    Myscanf(&a);
//    printf("%d\n",a);
//
//    return 0;
//}
/*
int g_a = 0;
//交换两个数字
void Swap_err1(int a, int b)//按值传递,没有传指针
{
    int tmp = a;
    a = b;
    b = tmp;
}

void Swap_err2(int* p1, int* p2)//没有解引用
{
    int* tmp = p1;
    p1 = p2;
    p2 = tmp;
}
//
//void Swap(int* p1, int* p2)//编译错误,老的编译器程序崩溃
//{
//    int* tmp;//tmp的值是随机值或者-858993460(0xcccccccc)

//    *tmp = *p1;//错误
//    *p1 = *p2;
//    *p2 = *tmp;
//}

void Swap(int* p1, int* p2)
{
    int tmp;
    tmp = *p1;
    *p1 = *p2;
    *p2 = tmp;
}

int main()
{
    int a = 10;
    int b = 20;

    Swap(&a,&b);

    printf("%d,%d\n",a,b);
    //g_a = 100;
    //tmp = 50;//error

    int c ;
    c = 20;
    //printf("%d\n",c);
    //int* tmp;//123
    //tmp = &c;
    //*tmp = 50;//c=50;

    return 0;
}
*/

//int main()
//{
//    int a = 10;
//    int b = 20;
//    int* p = &a;//int *p; p = &a;
//    *p = 100;//a = 100;
//    p = &b;
//    *p = 200;//b=200;
//    int * * pp = &p;
//    *pp = &a;//p = &a;
//    **pp = 1000;//a=1000;
//    *pp = &b;//p = &b;
//    **pp = 2000;//b=2000;
//
//    return 0;
//}

//int Max1(int a, int b)
//{
//    if (a >= b)
//        return a;
//    //if (a < b)
//    else
//        return b;
//}
//
//int main()
//{
//    printf("%d\n",Max1(10,5));//10
//    printf("%d\n", Max1(10, 50));//50
//    printf("%d\n", Max1(10, 10));//10
//
//    return 0;
//}

#define _CRT_SECURE_NO_WARNINGS//必须放在第一行
#include <stdio.h>
#include <assert.h>

/*
* 数组和指针的转换:
*    int arr[10] = {1,2,3,4,5};
*    int *p = arr;//p=&arr[0];
*    p[i] == *(p+i)
*    *(arr+i) ==arr[i]
* 建议:都使用下标访问元素

* 字符数组作为参数传递
*     只传字符串地址,不需要长度,通过'\0'标记结尾
* 断言:assert,
      表达式如果为真则什么也不发生,为假程序崩溃,同时提供错误信息
*/

//des = src;
//下标实现
void Mystrcpy1(char* des, char* src)
{
    int i = 0;
    for (; src[i] != '\0'; i++)
        des[i] = src[i];
    des[i] = '\0';
}

//指针1实现
void Mystrcpy2(char* des, char* src)
{
    int i = 0;
    for (; *(src + i) != '\0'; i++)
    {
        *(des + i) = *(src + i);
    }
    *(des+i) = '\0';
}

//指针实现2
void Mystrcpy3(char* des, char* src)
{
    while (*src != '\0')
    {
        *des = *src;
        des++;
        src++;
    }
    *des = '\0';
}

void Mystrcpy4(char* des, char* src)
{
    while (*src != '\0')
    {
        *des++ = *src++;//等价*(des++) = *(src++);
        //(* des)++ = ( * src)++;//error
    }
    *des = '\0';
}

void Mystrcpy(char* des, char* src)
{
    assert(des!=NULL && src!=NULL);
    if (des == NULL || src == NULL)
        return;

    while (*des++ = *src++) ;//经典代码
}

int Div(int a, int b)
{
    assert(b != 0);
    return a / b;
}

int main()
{
    char str1[10];
    char str2[10] = "abcd";
    Mystrcpy(str1,str2);
    printf("str1=%s\n",str1);

    Mystrcpy(NULL,str2);

    //int arr[10] = {1,2,3,4,5,6};
    //int* p = &arr[2];
    //printf("%d,%d\n",p[1],p[-1]);//*(p+1),*(p-1)

    /*int i = 0;
    while (i = 0)
    {
        printf("i==0\n");
    }*/

    int a;
    int b;
    scanf("%d%d",&a,&b);
    printf("%d\n",Div(a,b));

    return 0;
}

//void Fun(int** p)
//{
//    *p = NULL;
//}
//
//int main()
//{
//    int a = 10;
//    int* p = &a;
//    //p = NULL;
//    Fun(&p);
//    printf("%d\n",*p);
//
//    return 0;
//}

#if 0
//输入数据
void Input(int* arr, int len)
{
    for (int i = 0; i < len; i++)
    {
        scanf("%d",&arr[i]);//1
        //scanf("%d",arr+i);//2
        //scanf("%d",arr);//3
        //arr++;
    }
}

//最小值和第一个交换,最大值和最后一个交换
void Swap_arr(int* arr, int len)
{
    int minIndex = 0;//最小值下标
    int maxIndex = 0;//最大值下标
    for (int i = 0; i < len; i++)
    {
        if (arr[minIndex] > arr[i])
            minIndex = i;
        if (arr[maxIndex] < arr[i])
            maxIndex = i;
    }
    int tmp = arr[0];
    arr[0] = arr[minIndex];
    arr[minIndex] = tmp;

    tmp = arr[len - 1];
    arr[len - 1] = arr[maxIndex];
    arr[maxIndex] = tmp;
}

void Show21(int* arr, int len)
{
    for (int i = 0; i < len; i++)
    {
        printf("%d ",arr[i]);
    }
    printf("\n");
}

void Fun(int* arr, int len)//O(n),O(1)
{
    //int brr[len];//动态内存可以
    int tmp = arr[0];
    int i;
    int j;
    for (i = 0, j = len - 1; i < j; )
    {
        while ((i<j)&& arr[j] % 2 == 0)
            j--;
        arr[i] = arr[j];
        while ((i<j)&&arr[i] % 2 == 1)
            i++;
        arr[j] = arr[i];
    }
    arr[i] = tmp;
}

//冒泡排序
void BubbleSort(int* arr, int len)
{
    int tmp;
    for (int i = 0; i < len; i++)
    {
        for (int j = 0; j + 1 < len - i; j++)
        {
            if (arr[j] > arr[j + 1])
            {
                tmp = arr[j];
                arr[j] = arr[j + 1];
                arr[j+1] = tmp;
            }
        }
    }
}

//超过一半的数字
void Move(int* arr, int len)
{
    //先排序,再统计
}

int main()
{
    int arr[10];

    Input(arr,sizeof(arr)/sizeof(arr[0]));
    //Fun(arr, sizeof(arr) / sizeof(arr[0]));
    BubbleSort(arr, sizeof(arr) / sizeof(arr[0]));
    Show21(arr, sizeof(arr) / sizeof(arr[0]));

    return 0;
}
#endif 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值