我是靠谱客的博主 简单超短裙,最近开发中收集的这篇文章主要介绍C语言知识点总结(一),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一、指针
1、指针是一个变量,用来存放一块内存空间的地址。

2、指针的大小是固定的4/8个字节(32位平台/64位平台)。

3、 C/C++会把常量字符串存储到单独的一个内存区域,当几个指针。 指向同一个字符串的时候,他们实际会指向同一块内存。但是用相同的常量字符串去初始化不同的数组的时候就会开辟出不同的内存块。

4、 数组指针:一个能够指向数组的指针。数组指针中存放的应该是数组的地址。

int (*p)[10];
//解释:p先和*结合,说明p是一个指针变量,然后指着指向的是一个大小为10个整型的数组。所以p是一个指针,指向一个 数组,叫数组指针。
//这里要注意:[]的优先级要高于*号的,所以必须加上()来保证p先和*结合。

5、指针数组:一个存储指针的数组

int *arr[10]; //数组的每个元素是int*

6、函数指针:指向一个函数的指针

void (*fun)();
//fun先和*结合,说明fun是指针,指针指向的是一个函数,指向的函数无参数,返回值 类型为void。
int (*parr1[10])();//函数指针数组

7、回调函数:回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。

8、数组名的意义

  1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
  2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
  3. 除此之外所有的数组名都表示首元素的地址。

二、数据类型的存储
1、原码、反码、补码
计算机中的有符号数有三种表示方法,即原码、反码和补码。
三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,而数值位三种表示方法各不相同。
原码
直接将二进制按照正负数的形式翻译成二进制就可以。
反码
将原码的符号位不变,其他位依次按位取反就可以得到了。
补码
反码+1就得到补码。

2、在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理; 同 时,加法和减法也可以统一处理(CPU只有加法器)此外,补码与原码相互转换,其运算过程是相同的,不需 要额外的硬件电路。

3、大小端
大端(存储)模式:是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中。

小端(存储)模式:是指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地址中。

//判断大小端
#include<stdio.h>
int check_sys(){
int i = 1;
return (*(char*)& i);
}
//int check_sys(){
//	union{
//
int i;
//
char c;
//	}un;
//	un.i = 1;
//	return un.c;
//}
int main(){
int ret = check_sys();
if(ret==1){
printf("小端n");
}
else{
printf("大端n");
}
return 0;
}

三、字符函数
1、strlen size_t strlen ( const char * str ) 求字符串长度
字符串以’’ 作为结束标志,strlen函数返回的是在字符串中 ‘’ 前面出现的字符个数(不包含 ‘’ )。

参数指向的字符串必须要以 ‘’ 结束。

注意函数的返回值为size_t,是无符号的

//模拟实现
int _strlen(const char* str){
int count=0;
while(*str){
count++;
str++;
}
return count;
}
//不创建临时变量
int _strlen(const char* str){
if(*str=='')
return 0;
else
return 1+_strlen(str+1);
}

2、strcpy char* strcpy(char * destination, const char * source ) 拷贝字符串
源字符串必须以 ‘’ 结束。 (source)

会将源字符串中的 ‘’ 拷贝到目标空间。

目标空间必须足够大,以确保能存放源字符串。

目标空间必须可变。(destination)

char* _strcpy(char* dest,const char* src){
char* ret=dest;
assert(dest!=NULL && src!=NULL);
while((*dest++ = *src++)){
;
}
return ret;
}

3、strnpy char * strncpy ( char * destination, const char * source, size_t num )
拷贝num个字符从源字符串到目标空间。

如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。

4、strcmp int strcmp ( const char * str1, const char * str2 字符串比较
第一个字符串大于第二个字符串,则返回大于0的数字

第一个字符串等于第二个字符串,则返回0

第一个字符串小于第二个字符串,则返回小于0的数字

int _strcmp(const char* str1,const char* str2){
int ret=0;
assert(str1!=NULL && str2!=NULL);
while(!(ret = *(unsigned char *)str1 - *(unsigned char *)str2) && *str2){
++str1;
++str2;
}
if ( ret < 0 )
ret = -1 ;
else if ( ret > 0 )
ret = 1 ;
return( ret );
}

5、strncmp int strncmp ( const char * str1, const char * str2, size_t num 比较num个字符

6、strstr char * strstr ( const char *, const char * );
返回指向str1中第一次出现str2的指针,如果str2不是str1的一部分,则返回空指针。

7、memcpy void * memcpy ( void * destination, const void * source, size_t num )
函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。

这个函数在遇到 ‘’ 的时候并不会停下来。

如果source和destination有任何的重叠,复制的结果都是未定义的(不安全)。

void * _memcpy ( void * dst, const void * src, size_t count) {
void * ret = dst;
assert(dst);
assert(src);
while (count--) {
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
return(ret);
}

8、memmove void * memmove ( void * destination, const void * source, size_t num )
如果源空间和目标空间出现重叠,就得使用memmove函数处理

void * memmove ( void * dst, const void * src, size_t count) {
void * ret = dst;
if (dst <= src || (char *)dst >= ((char *)src + count)) {
while (count--) {
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
}
else {
dst = (char *)dst + count - 1;
src = (char *)src + count - 1;
while (count--) {
*(char *)dst = *(char *)src;
dst = (char *)dst - 1;
src = (char *)src - 1;
}
}
return(ret); }

四、自定义类型
1、结构体

//结构体自引用
typedef struct Node {
int data;
struct Node* next;
}Node;

2、内存对齐

  1. 第一个成员在与结构体变量偏移量为0的地址处。
  2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
  3. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
  4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所 有最大对齐数(含嵌套结构体的对齐数)的整数倍。

对齐数 = 编译器默认的一个对齐数与该成员大小的较小值
vs默认为8,Linux默认为4

结构体的内存对齐是拿空间来换取时间的做法。
修改默认对齐数

#pragma pack(8)//设置默认对齐数为8
#pragma pack()//取消设置的默认对齐数,还原为默认

3、枚举

enum Color//颜色 
{
RED,
GREEN,
BLUE
};

枚举的优点

  1. 增加代码的可读性和可维护性
  2. 和#define定义的标识符比较枚举有类型检查,更加严谨。
  3. 防止了命名污染(封装)
  4. 便于调试
  5. 使用方便,一次可以定义多个常量

4、联合
联合也是一种特殊的自定义类型 这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间(所以 联合也叫共用体)。

联合的大小至少是最大成员的大小。

当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。

最后

以上就是简单超短裙为你收集整理的C语言知识点总结(一)的全部内容,希望文章能够帮你解决C语言知识点总结(一)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(53)

评论列表共有 0 条评论

立即
投稿
返回
顶部