C语言以及linux系统的知识点概要

关于C语言以及linux系统的知识点

scanf()根据一个%d读取一个数值
每次读取前都跳过数值前的所有空白字符(空格、tab、换行符)
直到遇到非空白字符才开始读取
scanf的返回值,成功返回输入项目的个数
ret = scanf(“%d”, &chose);
if (ret != 1) {
printf(“input chose error\n”);
return -1;
}

字符型数组在内存中的储存方式同String类一样,
故输出数组名并不是输出数组首地址,而是直接输出数组内容直到/0;
而整形数组只是整形的集合,所以其数组名仅仅是其首地址,
我们必须要用for循环才能完整的输出整个整形数组

判断大小端存储
小端存储(X86):数据低位存储在地址低位,数据高位存储在地址高位
大端存储:数据低位存储在地址高位,数据高位存储在地址低位
#include <stdio.h>
int main(int argc, const char *argv[])
{//方法1:指针
// int a = 0x12345678;
// char *p = (char *)&a;
// if (0x78 == *p)
// {
// printf(“小端\n”);
// }
// else if (0x12 == *p)
// {
// printf(“大端\n”);
// }
//方法2:联合体
union A
{
int a;
char b;
};

union A n;
n.a = 0x12345678;

if (0x78 == n.b)
{
    printf("小端\n");
}
else if (0x12 == n.b)
{
    printf("大端\n");
}
return 0;

}

unsigned 在32位和64位系统中都占用4字节

struct C {
char s[0];
};
//此时数组是s为柔性数组,在构造体中不分配空间,所以字节数为0
printf(“%d\n”,sizeof(struct C));//0字节
柔性数组参考csdn链接
https://blog.csdn.net/weixin_42096901/article/details/117331944?ops_request_misc=&request_id=&biz_id=102&utm_term=%E6%9F%94%E6%80%A7%E6%95%B0%E7%BB%84&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-0-117331944.nonecase&spm=1018.2226.3001.4187

C高级day3 3动态申请分配内存
栈区分配空间是根据定义实时向下申请,生命周期结束后自动被系统回收
堆区是由malloc动态申请 从下向上方式申请 整个程序结束或者free释放
当栈区和堆区申请内存碰头时间,表示系统内存空间满

换行的方式

puts(""); putchar(10); putchar('\n'); putchar('\12');
putchar('\xa'); printf("\n");

当用scanf输入时,可能会产生垃圾字符,
可以用 while(getchar()!=(‘\n’)) 处理

用malloc申请空间时间,可以根据返回值判断申请内存是否成功

int n=malloc(sizeof(int [10]))
if(NULL==n){
printf(“内存申请失败,请重试”);
}

if (a != NULL) {
free(a); //释放a指向的内存,但是释放后a指向的这个指针并没有断开
a = NULL; //断开指针指向
}

冒泡排序函数的封装

#include <stdio.h>
//冒泡排序的升降函数
//flag 0 升序   1  降序
int sort(int *p, int len, int flag){
    if(NULL == p){
        printf("入参为NULL,排序失败\n");
        return -1;
    }
    int i = 0;
    int j = 0;
    int temp = 0;
    if(0 == flag){
        for(i = 0; i < len-1; i++){
            for(j = 0; j < len-1-i; j++){
                if(p[j] > p[j+1]){
                    temp = p[j];
                    p[j] = p[j+1];
                    p[j+1] = temp;
                }
            }
        }
    }else if(1 == flag){
        for(i = 0; i < len-1; i++){
            for(j = 0; j < len-1-i; j++){
                if(*(p+j) < *(p+j+1)){
                    temp = *(p+j);
                    *(p+j) = *(p+j+1);
                    *(p+j+1) = temp;
                }
            }
        }
    }
    return 0;
}

int print_array(int *p, int len){
    int i = 0;
    for(i = 0; i < len; i++){
        printf("%d  ", p[i]);
    }
    putchar(10);
}

int main(int argc, const char *argv[])
{
	int s[5] = {67, 45, 18, 96, 10};
	print_array(s, 5);

	sort(s, 5, 0);
	print_array(s, 5);

	sort(s, 5, 1);
	print_array(s, 5);

	return 0;
}

优化后的冒泡排序

 stu_t stu;
    int i,j,flag;
    for(i=0;i<cls->n;i++){
        for(j=0;j<cls->n;j++){
            if(cls->stu[j].score  >  cls->stu[j+1].score ){
                stu = cls->stu[j];
                cls->stu[j] = cls->stu[j+1];
                cls->stu[j+1] = stu;
                flag=1;
            }
        }
        if(0==flag){//表示上一步没有进入if循环,此时已经有序排列,减少了多余的排列
            break;
        }
    }

删除思想
//2.删除功能的实现
//功能:根据输入的学生姓名,删除对应的学生
//参数:班级的指针
//返回值:成功返回删除的学生个数,失败则返回-1
int del_student (class_t *cls){
char name[20]={0};
//1.判断班级是否为空
if(class_t_empty(cls)){
printf(“班级内没有学生\n”);
return -1;
}
//2.输入删除想要删除的学生名单
printf(“请输入想要删除的学生\n”);
scanf(“%s”,name);
while(getchar()!=‘\n’);
//3.拿输入的学生姓名和班级内的学生进行比较
int i=0,j=0;
for(i=0,j=0;in;i++){
if(strcmp(name,(cls->stu[i].name))){//输入学生的姓名和班级内某个学生相等的时间不进入if语句,i一直加
cls->stu[j]= cls->stu[i]; //不相等就进入if语句,将i此时的下标给到j,完成位置的替换
j++;
}
}
//4.修改班级内n的值
cls->n -= (i-j);
//5.返回值
return (i-j);
}

//字符串的颠倒
#include <stdio.h>

int main(int argc, const char *argv[])
{

char data[12] = "hello  world";
char *p1 = data;
char *p2 = data;
while (*p2 != '\0')
{
    p2++;
}
p2 -= 1;

char tmp;
while (p2 > p1)
{
    tmp = *p1;
    *(p1++) = *p2;
    *(p2--) = tmp;
}

printf("data = %s\n", data);

return 0;

}

内存清零的函数
从&A地址开始,向后sizeof(struct AA)大小的内存,全部设置为0
memset(&A,0,sizeof(struct AA));

永远不要返回局部变量的地址,作用周期结束后就被系统回收了
栈区:局部变量或者函数的执行 满减栈
32位系统下,寄存器为4字节,cpu从cache(高速缓存区)拿数据要从寄存器中拿数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iyRvxzmg-1658410452600)(C:\Users\admin\Desktop\内存空间.png)]

long double 32位 12字节 64位16字节
sizeof不是函数,可以不加括号使用,是个关键字
typedf 是关键字 在预处理阶段
define是预处理指令

编译分为预处理,编译,汇编,链接
预处理:宏定义的替换和头文件的展开
gcc -E hello.c -o hello.i
编译:做语法分析和词法分析,起到查错的作用,如果语法词法都没有错,生成汇编文件
gcc -S hello.i -o hello.s
汇编:将汇编文件生成二进制文件,用来给计算机识别
gcc -c hello.s -o hello.o
链接:链接库文件(函数的定义),最终生成可执行的a.out文件

//内存清零的函数
//从&A地址开始,向后sizeof(struct AA)大小的内存,全部设置为0
memset(&A,0,sizeof(struct AA));

练习题:

1.下面程序输出的结果为(B)
	int main(){
	int a[]={1,2,3,4,5,6,7,8,9,10,11,12},*p=a+5,*q=NULL;
		*q=*(p+5);//*q指向的是NULL,也就是q没有指向任何变量
		          //把一个常量赋值给一个不存在的NULL,是行不通的
				  //可以指向一个新地址
		printf("%d %d\n",*p,*q);
	}
	(B)
	A.5 10
	B.运行后报错
	C.6 11
	D.6 6



2.已有定义:
	int i,a[10],*p;
	则合法的赋值语句是(C)
	
	A.p=a[2]+2;
	B.p=a[5];
	C.p=a+3;//a此时代表数组的首地址,a+3表示偏移3个int型的数据,此时指针指向a[3]
	D.p=100;


3.下面程序输出的结果为(B)
	int main(){
		int a[]={2,4,6,8,10}, y=0, x, *p;
		p=&a[1];
		for(x=1; x<3; x++)
			y+=p[x];
		printf("%d\n", y);
	}
	
	A.10
	B.14
 	C.24
	D.18


4.设有定义语句
	int x[6]={2,4,6,8,5,7},*p=x,i;
	要求依次输出x数组6个元素中的值,不能完成此操作的语句是(D)

	A.for(i=0;i<6;i++) printf("%2d",*p++);
	B.for(i=0;i<6;i++) printf("%2d",*(p++));
	C.for(i=0;i<6;i++) printf("%2d",*(p+i));
	D.for(i=0;i<6;i++) printf("%2d",(*p)++);


5.下面代码会输出什么?  0
	int main(){
		char s[] = "ABCD";
		char *p;
		p = s;
		printf("%d\n", *(p+4));
	}


6.下面程序输出的结果为(B)
	int main(){
		char s[] = "hello world";
		printf("%d\n",s[strlen(s)-1]-s[sizeof(s)-11]);
	}
	
	A.-8
	B.-1
	C.8
	D.1
	
	
	
7.下列的定义及操作,错误的是(D)
	A.char s[10] = {'\0'};s[1] = 'H';
	B.char s[10] = {'0'};s[1] = 'Q';
	C.char s[10] = {0};s[1] = 'Y';
	D.char s[] = {'\0'};s[1] = 'J';
	
	
	

s;
printf(“%d\n”, *(p+4));
}

6.下面程序输出的结果为(B)
int main(){
char s[] = “hello world”;
printf(“%d\n”,s[strlen(s)-1]-s[sizeof(s)-11]);
}

A.-8
B.-1
C.8
D.1

7.下列的定义及操作,错误的是(D)
A.char s[10] = {‘\0’};s[1] = ‘H’;
B.char s[10] = {‘0’};s[1] = ‘Q’;
C.char s[10] = {0};s[1] = ‘Y’;
D.char s[] = {‘\0’};s[1] = ‘J’;


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值