zoukankan      html  css  js  c++  java
  • C/C++练习题(二)

    1、下面这些指针分别代表什么?

    float(**p1)[10];
    double*(*p2)[10];
    double(*p3[10])();
    int*((*p4)[10]);
    long(**p5)(int(*a)[]);
    

    p1是一个二维指针,它指向的一维指针又指向了一个数组,这个数组的类型是float[10];
    p2是一个指针,它指向了一片数组,这个数组的每个元素的类型是double
    p3是一个10个元素的数组,数组的每个元素都是一个函数指针,即double(
    )();
    p4是一个二维指针,这个二维指针指向了一个函数指针(注意指向的不是函数而是函数指针),这个函数指针指向的函数的返回值是long,参数是一个指向类型为int大小为10的一个数组。



    2、查找字符串中第一个只出现一次的字符并输出。(如:aabbcddefg 则输出 'c')

    分析:这个问题只要考察是否有空间换时间的思想。
    因为这里出现的都是ASCII码,所以我们建立一个大小为256的数组,之后遍历字符串,以字符串中的字符为下标累加数组元素,这样我们就可以得到一个直方图。

    void findOneChar(const char* str)
    {
    	int array[256] = {0};
    	char* p = (char*)s;
    
    	while( *p )
    	{
    		array[*p++]++;
    	}
    	while( *s && (array[*s] != 1) )
    	{
    		s++;
    	}
    	printf("%c
    ", *s);
    }
    

    1、下面程序有问题吗?如果有,请指出。

    #include <stdio.h>
    char* ptr = (char*)malloc(10);
    
    void main(void)
    {
    	if(NULL == ptr)
    	{
    		printf("malloc failed!
    ");
    		return;
    	}
    	else
    	{
    		// Do something...
    	}
    	return;
    }
    
    1、程序中使用了malloc,起码要包含一些头文件吧; 2、ptr是全局变量,全局变量要使用常量来初始化。这里会编译出错。 3、即使忽略上面的情况,程序也可能会造成内存泄露,大家可能认为现代OS在进程结束的时候就会回收这个进程申请的内存资源,但是如果致力于嵌入式开发,我们就需要考虑一些小型的操作系统,因为一些特殊的目的并没有实现这样的自动回收功能,所以,必须要谨慎。

    2、下面程序有问题吗?如果有,请指出并修改。

    #include <stdio.h>
    
    int main(int argc, char* argv[])
    {
    	int flag = 0;
    	char passwd[10];
    	memset(passwd, 0, sizeof(passwd));
    	strcpy(passwd, argv[1]);
    
    	if(0 == strcmp("LinuxGeek", passwd))
    	{
    		flag = 1;
    	}
    	
    	if(flag)
    	{
    		printf("PASS
    ");
    	}
    	else
    	{
    		printf("ERROR
    ");
    	}
    	
    }
    

    除开那些包含头文件之类的错误,这个程序最大的问题就是安全性。 这个程序从功能来看是用来检测密码的,如果用户输入LinuxGeek的时候通过检测,但是由于使用了strcpy和strcmp,那么当用户输入超过10的时候就会产生越界。**由于栈地址是从高地址往低地址增长的,所以passwd后面的空间恰好是flag对应的空间**,这样当输入超过长度为10的字符串时,flag就会被修改成非0值**(经过测试bcc32 结果为error , qt下为pass,所以有没有污染还是要看编译器,但是我们不能编写依赖编译器的代码,一定要规范。)**,于是检测通过,PASS就会被输出。 所以我们应该使用strncpy和strncmp来加强安全性。


    3、有两个程序a和b都有相同的代码,如下:
    int buffer[16]
    ......
    printf("%p", &buffer[0]);
    printf("buffer[0] = %d", buffer[0]);

    同时运行a和b最终程序输出:
    0x20001300 buffer[0] = 100
    0x20001300 buffer[0] = 1000

    为什么会有相同和不同的结果??


    首先,为什么两个程序的数组地址居然一样呢?
    题目没有说明是什么样的数组,是全局的还是局部的,但是两个程序的代码是一样的,如果使用相同的编译器的话,最终生成的可执行程序也是一样的。

    好,现在程序运行成为进程。
    要知道,现代操作系统都有虚拟空间的,每个进程独享自己的4G虚拟空间,所以说这里的地址一样。程序运行的实际物理地址是不一样的,但是我们看不到;至于buffer[0]的值不同,是因为没有初始化,值是随机的。

  • 相关阅读:
    python-打包程序
    python-记log
    Git-分支
    跨线程调用控件之MethodInvoker
    c# Invoke和BeginInvoke 区别
    winform 开发之Control.InvokeRequired
    C#三种定时器的实现
    winform窗口打开后文本框的默认焦点设置
    C#在Winform中改变Textbox高度三种方法
    Json.net/Newtonsoft 3.0 新特性JObject/Linq to Json
  • 原文地址:https://www.cnblogs.com/lvonve/p/8832461.html
Copyright © 2011-2022 走看看