C语言变量和指针

简介: C语言变量和指针

一、变量


非静态局部变量的作用域是函数里面的所有语句, 生命周期是函数某一次执行的时间


静态局部变量的作用域是函数里面的所有语句, 生命周期是没有限制的


静态全局变量的作用域只包含它所在文件里的所有语句,生命周期也是没有限制的


非静态全局变量的作用域和生命周期都是没有限制的


#include <stdio.h>
int val1 = 0;    //非静态全局变量
static int val3 = 0;   //静态全局变量
int main() {
    int val = 0;   //非静态局部变量
    static int val2 = 0;   //静态局部变量
    return 0;
}


#include <stdio.h>
//这个函数可以用来计算多个数字的和
int sum(int val) {
    static int ret = 0;  //静态变量的初始化只在程序开始的时候执行一次,和这条语句所在的位置无关
    ret += val;   //每次ret变量里都保留上一次sum函数结束时的内容
    return ret;
}
int main() {
    int num = 0;
    for (num = 1;num <= 5;num++) {
        printf("%d\n", sum(num));
    }
    return 0;
}


二、指针


1、指针变量


#include <stdio.h>
typedef int *pint_t;   //给整数类型指针起名字叫pint_t,以后就可以在程序里用pint_t代表指针类型
int main() {
    int val = 0;
    int *p_val = &val, *p_val1 = NULL/*空地址*/;   //*表示变量是一个指针变量
    //pint_t p_val, p_val1;  //声明两个整数类型指针
    p_val = &val;  //把val变量存储区的地址赋值给指针p_val,可以认为以后指针p_val就指向了变量val
    *p_val = 10;   //指针变量名称前使用*操作符可以表示指针指向的变量(存储区)
    printf("val是%d\n", val);
    return 0;
}


2、交换数据


#include <stdio.h>
int main() {
    int val = 3, val1 = 7;
    int *p_val = &val, *p_val1 = &val1; //声明两个指针分别指向这两个整数变量
    /*val ^= val1;
    val1 ^= val;
    val ^= val1;
    printf("val是%d,val1是%d\n", val, val1);*/
    *p_val ^= *p_val1;
    *p_val1 ^= *p_val;
    *p_val ^= *p_val1;
    printf("*p_val是%d, *p_val1是%d\n", *p_val, *p_val1);
    return 0;
}


3、判断大小


#include <stdio.h>
int main() {
    int val = 0, val1 = 0, val2 = 0;
    int *p_min = &val;   //p_min指针永远指向最小数字所在的存储区
    printf("请输入三个数字:");
    scanf("%d%d%d", &val, &val1, &val2);
    if (*p_min > val1) {
        //处理val1里的数字比val更小的情况
        p_min = &val1;
    }
    if (*p_min > val2) {
        //val2变量里的数字更小
        p_min = &val2;
    }
    printf("最小数字是%d\n", *p_min);
    return 0;
}


4、指针加减运算


#include <stdio.h>
int main() {
    int arr[] = {1, 2, 3, 4, 5};
    int *p_val = arr;
    int num = 0;
    printf("arr是%p\n", arr);
    printf("arr + 1是%p\n", arr + 1);
    printf("arr - 1是%p\n", arr - 1);
    for (num = 0;num <= 4;num++) {
        printf("%d ", arr[num]);
        printf("%d ", *(arr + num/*得到下标为num存储区的地址*/)/*下标为num的存储区*/);
        printf("%d ", *(p_val + num/*得到下标为num存储区的地址*/)/*下标为num的存储区*/);
    }
    printf("\n");
    printf("&arr[3] - arr是%d\n", &arr[3] - arr);  //结果是3,表示两个地址之间包含3个整数类型存储区
    return 0;
}
arr是00EFFBAC
arr + 1是00EFFBB0
arr - 1是00EFFBA8
1 1 1 2 2 2 3 3 3 4 4 4 5 5 5
&arr[3] - arr是3


5、指针加1,相当于加该数据类型的大小


#include <stdio.h>
int main() {
    int arr[] = {1, 2, 3, 4, 5};
    int *p_tmp = NULL;
    for (p_tmp = arr;p_tmp <= arr + 4/*最后一个存储区的地址*/;p_tmp++) {
        printf("%d ", *p_tmp);
    }
    printf("\n");
    return 0;
}


6、const关键字


#include <stdio.h>
int main() {
    int val = 0;
    const int *p_val = &val;   //不可以通过这种指针对它指向的存储区做赋值操作
    int * const p_val1 = &val; //不可以对这种指针本身做赋值
    //*p_val = 10;     错误
    p_val = NULL;
    *p_val1 = 10;
    //p_val1 = NULL;   错误
    return 0;
}


7、无类型指针


#include <stdio.h>
int main() {
    char ch = 'e';
    int val = 34;
    float fval = 6.3f;
    void *p_v = NULL;  //无类型指针
    p_v = &ch;   //无类型指针指向字符类型存储区
    printf("%c\n", *(char *)p_v);
    p_v = &val;
    printf("%d\n", *(int *)p_v);
    p_v = &fval;
    printf("%g\n", *(float *)p_v);
    return 0;
}


8、指针参数


#include <stdio.h>
void print(const int *p_val/*数组形参的本质就是一个指针*/, int size) {
    int num = 0;
    for (num = 0;num <= size - 1;num++) {
        printf("%d ", *(p_val + num));
    }
    printf("\n");
}
int main() {
    int arr[] = {1, 2, 3, 4, 5};
    print(arr, 5);
    return 0;
}


9、返回值为地址


#include <stdio.h>
int * /*指针类型存储区用来存放作为返回值的地址*/read(void) {
    static int val = 0;
    printf("请输入一个数字:");
    scanf("%d", &val);
    return &val;
}
int main() {
    int *p_val = read();
    printf("数字是%d\n", *p_val/*表示read函数里val变量存储区*/);
    return 0;
}


10、通过指针判断大小


#include <stdio.h>
int *max(const int *p_val, int size) {
    const int *p_max = p_val;    //为了和p_val指针一致所以声明的时候需要使用const关键字
    const int *p_tmp = NULL;
    //指针循环变量从第二个存储区开始一直
    //指到最后一个存储区为止
    for (p_tmp = p_val + 1;p_tmp <= p_val + size - 1;p_tmp++) {
        if (*p_tmp > *p_max) {
            //当前存储区内容比p_max指针指向的
            //存储区内容还大
            //这个时候当前存储区更有资格
            //成为最后的结果
            p_max = p_tmp;    //p_max指针指向当前存储区
        }
    }
    return (int *)p_max;
}
int main() {
    int arr[] = {40, 80, 30, 60, 20, 50};
    int *p_max = max(arr, 6);
    printf("最大数字是%d\n", *p_max);
    return 0;
}


11、交换数组里面的数值


#include <stdio.h>
int * /*用返回值代表处理结果*/reverse(int *p_val, int size) {
    int *p_head = p_val;   //永远指向配对存储区中前面的那个,开始时指向第一个存储区
    int *p_tail = p_val + size - 1;  //永远指向配对存储区里后面那个存储区,开始时指向最后一个存储区
    //每循环一次把一对配对存储区的内容
    //做交换
    while (p_head < p_tail) {  //两个指针既没有相遇也没有交错
        //把两个指针指向的存储区内容做交换
        //就可以了
        *p_head ^= *p_tail;
        *p_tail ^= *p_head;
        *p_head ^= *p_tail;
        p_head++;   //p_head指针指向下一对存储区
                    //里前面那个
        p_tail--;   //p_tail指针指向下一对存储区
                    //里后面那个
    }
    return p_val;   //把数组里第一个存储区的地址做返回值
}
int main() {
    int arr[] = {1, 2, 3, 4, 5, 6};
    int num = 0;
    reverse(arr, 6);
    for (num = 0;num <= 5;num++) {
        printf("%d ", arr[num]);
    }
    printf("\n");
    return 0;
}


目录
相关文章
|
2月前
|
存储 NoSQL 编译器
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
指针是一个变量,它存储另一个变量的内存地址。换句话说,指针“指向”存储在内存中的某个数据。
123 3
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
|
2月前
|
存储 编译器 C语言
【C语言】C语言的变量和声明系统性讲解
在C语言中,声明和定义是两个关键概念,分别用于告知编译器变量或函数的存在(声明)和实际创建及分配内存(定义)。声明可以多次出现,而定义只能有一次。声明通常位于头文件中,定义则在源文件中。通过合理组织头文件和源文件,可以提高代码的模块化和可维护性。示例包括全局变量、局部变量、函数、结构体、联合体、数组、字符串、枚举和指针的声明与定义。
79 12
|
2月前
|
存储 编译器 C语言
【C语言】指针大小知多少 ?一场探寻C语言深处的冒险 !
在C语言中,指针的大小(即指针变量占用的内存大小)是由计算机的体系结构(例如32位还是64位)和编译器决定的。
157 9
|
2月前
|
安全 程序员 C语言
【C语言】指针的爱恨纠葛:常量指针vs指向常量的指针
在C语言中,“常量指针”和“指向常量的指针”是两个重要的指针概念。它们在控制指针的行为和数据的可修改性方面发挥着关键作用。理解这两个概念有助于编写更安全、有效的代码。本文将深入探讨这两个概念,包括定义、语法、实际应用、复杂示例、最佳实践以及常见问题。
60 7
|
2月前
|
C语言
【C语言】全局搜索变量却找不到定义?原来是因为宏!
使用条件编译和 `extern` 来管理全局变量的定义和声明是一种有效的技术,但应谨慎使用。在可能的情况下,应该优先考虑使用局部变量、函数参数和返回值、静态变量或者更高级的封装技术(如结构体和类)来减少全局变量的使用。
50 5
|
3月前
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
3月前
|
算法 C语言
C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项
本文深入讲解了C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项,通过实例演示了文件操作的基本流程,帮助读者掌握这一重要技能,提升程序开发能力。
211 3
|
3月前
|
存储 算法 程序员
C 语言指针详解 —— 内存操控的魔法棒
《C 语言指针详解》深入浅出地讲解了指针的概念、使用方法及其在内存操作中的重要作用,被誉为程序员手中的“内存操控魔法棒”。本书适合C语言初学者及希望深化理解指针机制的开发者阅读。
|
3月前
|
程序员 C语言
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门。本文深入探讨了指针的基本概念、声明方式、动态内存分配、函数参数传递、指针运算及与数组和函数的关系,强调了正确使用指针的重要性,并鼓励读者通过实践掌握这一关键技能。
71 1
|
3月前
|
存储 C语言 计算机视觉
在C语言中指针数组和数组指针在动态内存分配中的应用
在C语言中,指针数组和数组指针均可用于动态内存分配。指针数组是数组的每个元素都是指针,可用于指向多个动态分配的内存块;数组指针则指向一个数组,可动态分配和管理大型数据结构。两者结合使用,灵活高效地管理内存。

热门文章

最新文章