欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C/C++学习

程序员文章站 2022-03-05 13:09:30
...

1、sizeof和strlen
①sizeof是一种运算符,而strlen是C的一个库函数(头文件:sting.h);举例说明,
例一,char str[2] = “A”,sizeof(str) = 2,而strlen(str) = 1;sizeof计算的是str所占的内存空间(2字节),而strlen计算的是实际的数据大小(1字节)。
例二,int a[1] = {10},sizeof(a) = 4,而strlen(a)编译器会报错,我是Linux下编译,错误信息为:invalid conversion from ‘int’to ‘const char*’如果使用强制转换类型strlen((char*)a),编译通过,输出:1。因此得出结论,strlen计算的必须是字符型,且必须是以“\0”结尾的。
例三,为了进一步说明二者的计算内容,举例如下:

char str[20] = "0123456789";
int a = strlen(str); //a = 10
int b = sizeof(str); //b = 20;

这个问题是之前一个小程序需要用数组的成员的个数作为参数传到被调用函数中作为条件进行判断,一开始用的sizeof,发现结果不对,后来突然想到sizeof计算的是变量所占据的内存的大小,比如char str[2] = “A”,所占据内存大小为 1字节 * 2 = 2字节,但str里只有一个值“A”,所以strlen计算的结果为1,如果计算的是数组成员个数,需要strlen[变量名] / sizeof(变量类型),为了规范代码,哪怕是char类型,最好也写成strlen(str) / sizeof(char)。
②数组做sizeof的参数不退化,传递给strlen就退回成指针(数组作为参数传给函数时传的是指针而不是数组,传递的是数组的首地址,如fun(char [8])、fun(char [])都等价于fun(char *)。在C++里传递数组永远都是传递指向数组首元素的指针,编译器不知道数组的大小。);当使用了一个结构体类型或变量时,sizeof返回实际的大小。当使用静态的空间数组时,sizeof返回全部数组的尺寸。sizeof操作符不能返回被动态分配的数组或外部的数组的尺寸。

2、关于数组初始化
新建一个数组后,需要对数组进行初始化,不然会打印出一些垃圾值,比如:

#include <stdio.h>
#include <string.h>

using namespace std;

int main()
{
    char str[10];
    memset(str,0,sizeof(str)); // 初始化操作
    printf("%d\n",sizeof(str)); //1
    printf("%d\n",strlen(str)); //2
    return 0;
}

如果上述代码没有进行memset,1会打印:10,2则打印一些垃圾值(和分配的内存有关);如果加上memset,1打印:10,2打印:0。

3、函数指针和指针函数
主要看后两个字,函数指针本质上是一个指针,只不过这个指针指向了一个函数;指针函数本质上是一个函数,这个函数的返回值是指针

4、指针数组和数组指针
指针数组:array of pointers,即用于存储指针的数组,也就是数组元素都是指针;
数组指针:a pointer to an array,即指向数组的指针;形式表现见下:
int* a[4] //1、指针数组
int (*a)[4] //2、数组指针
其实很好理解,根据C语言表达式的右结合律来分析,*(间接引用运算符) 的优先级低于 [] 的优先级,表达式1是数组,然后数组里面存储了指针,表达式2的()优先级最高,所以2首先是指针,这个指针指向了一个数组

5、指针与地址
阅读以下代码:

#include <stdio.h>

using namespace std;

int main()
{
    int *p;
    int a[3] = {2,4,6};
    p = a;
    printf("%d\n",*p+1);    //a打印:3
    printf("%d\n",*(p+1));  //b打印:4
    printf("%x\n",p);           //c打印内存地址(每次输出结果不同,主要看程序编译时,内存分配的情况):e28ae630
    printf("%x\n",p+1);     //d打印内存地址(每次输出结果不同,主要看程序编译时,内存分配的情况):e28ae634
}

a的意思是*p指向a[3]的首地址,即a[0],该地址存的数据是2,然后计算2+1,所以输出3;
b的意思是*p指向了a[3]的第二位,即a[1],该地址存的是4,所以输出4;
c的意思是p指向的地址,打印出来的是内存地址;
d的意思与c相同,不过因为定义的p是int型,占据4字节,所以p+1的地址比p的地址多了4;

未完待续

相关标签: c语言

上一篇: Java学习笔记

下一篇: C++/C学习